Copilot commented on code in PR #24426:
URL: https://github.com/apache/camel/pull/24426#discussion_r3523960870


##########
components/camel-cxf/camel-cxf-soap/src/main/java/org/apache/camel/component/cxf/jaxws/CxfConsumer.java:
##########
@@ -402,9 +409,84 @@ private static Throwable 
extractFromBody(org.apache.camel.Exchange camelExchange
             Object body = camelExchange.getMessage().getBody();
             if (body instanceof Throwable throwable) {
                 t = throwable;
+            } else if (body instanceof CxfPayload<?> payload) {
+                // Check if the CxfPayload contains a SOAP Fault element set 
directly as body
+                t = extractFaultFromPayload(payload);
             }
             return t;
         }
 
+        /**
+         * Detects a SOAP Fault element inside a CxfPayload body and converts 
it to a proper SoapFault. This handles the
+         * case where a route sets a CxfPayload containing a raw {@code 
<soap:Fault>} XML element directly on the
+         * message body, ensuring it is routed through CXF's standard fault 
handling path rather than the normal
+         * response path.
+         */
+        private static SoapFault extractFaultFromPayload(CxfPayload<?> 
payload) {
+            List<Element> elements = payload.getBody();
+            if (elements == null || elements.size() != 1) {
+                return null;
+            }
+            Element element = elements.get(0);
+            if (!"Fault".equals(element.getLocalName())) {
+                return null;
+            }
+            String nsUri = element.getNamespaceURI();
+            if (!"http://schemas.xmlsoap.org/soap/envelope/".equals(nsUri)
+                    && 
!"http://www.w3.org/2003/05/soap-envelope".equals(nsUri)) {
+                return null;
+            }
+
+            // Extract faultcode, faultstring, and detail from the Fault 
element
+            String faultString = null;
+            QName faultCode = null;
+            Element detail = null;
+
+            NodeList children = element.getChildNodes();
+            for (int i = 0; i < children.getLength(); i++) {
+                Node child = children.item(i);
+                if (child.getNodeType() != Node.ELEMENT_NODE) {
+                    continue;
+                }
+                Element childElem = (Element) child;
+                String localName = childElem.getLocalName();
+                if ("faultcode".equals(localName) || "Code".equals(localName)) 
{
+                    faultCode = parseFaultCode(element, childElem);
+                } else if ("faultstring".equals(localName) || 
"Reason".equals(localName)) {
+                    faultString = childElem.getTextContent();
+                } else if ("detail".equals(localName) || 
"Detail".equals(localName)) {
+                    detail = childElem;
+                }
+            }
+
+            if (faultCode == null) {
+                faultCode = new QName(nsUri, "Server");
+            }
+            SoapFault fault = new SoapFault(faultString != null ? faultString 
: "", faultCode);
+            if (detail != null) {
+                fault.setDetail(detail);
+            }
+            return fault;
+        }
+
+        private static QName parseFaultCode(Element faultElement, Element 
codeElement) {
+            String codeText = codeElement.getTextContent();
+            if (codeText == null || codeText.isBlank()) {
+                return null;
+            }
+            codeText = codeText.trim();
+            int colonIndex = codeText.indexOf(':');
+            if (colonIndex > 0) {
+                String prefix = codeText.substring(0, colonIndex);
+                String localPart = codeText.substring(colonIndex + 1);
+                String namespaceURI = faultElement.lookupNamespaceURI(prefix);
+                if (namespaceURI != null) {
+                    return new QName(namespaceURI, localPart, prefix);
+                }
+                return new QName("", localPart, prefix);

Review Comment:
   `parseFaultCode` resolves the QName prefix via 
`faultElement.lookupNamespaceURI(prefix)`. Namespace declarations on the 
`<faultcode>`/`<Code>` element itself are not visible when looking up from the 
parent `<Fault>` element, so this can incorrectly produce a QName with an empty 
namespace even though the prefix is properly declared in-scope on the code 
element.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to