@@ -5,12 +5,12 @@ package response
55import (
66 "bytes"
77 "encoding/json"
8- "encoding/xml"
98 "fmt"
109 "io"
1110 "net/http"
1211 "strings"
1312
13+ "github.com/antchfx/xmlquery"
1414 "github.com/deploymenttheory/go-api-http-client/logger"
1515 "golang.org/x/net/html"
1616)
@@ -108,38 +108,41 @@ func parseJSONResponse(bodyBytes []byte, apiError *APIError, log logger.Logger,
108108 }
109109}
110110
111- // parseXMLResponse should be implemented to parse XML responses and log errors using the centralized logger .
111+ // parseXMLResponse dynamically parses XML error responses and accumulates potential error messages .
112112func parseXMLResponse (bodyBytes []byte , apiError * APIError , log logger.Logger , resp * http.Response ) {
113- var xmlErr APIError
113+ // Always set the Raw field to the entire XML content for debugging purposes
114+ apiError .Raw = string (bodyBytes )
114115
115- // Attempt to unmarshal the XML body into the XMLErrorResponse struct
116- if err := xml .Unmarshal (bodyBytes , & xmlErr ); err != nil {
117- // If parsing fails, log the error and keep the raw response
118- apiError .Raw = string (bodyBytes )
119- log .LogError ("xml_parsing_error" ,
120- resp .Request .Method ,
121- resp .Request .URL .String (),
122- apiError .StatusCode ,
123- fmt .Sprintf ("Failed to parse XML: %s" , err ),
124- err ,
125- apiError .Raw ,
126- )
127- } else {
128- // Update the APIError with information from the parsed XML
129- apiError .Message = xmlErr .Message
130- // Assuming you might want to add a 'Code' field to APIError to store xmlErr.Code
131- // apiError.Code = xmlErr.Code
116+ // Parse the XML document
117+ doc , err := xmlquery .Parse (bytes .NewReader (bodyBytes ))
118+ if err != nil {
119+ logError (log , apiError , "xml_parsing_error" , resp )
120+ return
121+ }
132122
133- // Log the parsed error details
134- log . LogError ( "xml_error_detected" ,
135- resp . Request . Method ,
136- resp . Request . URL . String (),
137- apiError . StatusCode ,
138- "Parsed XML error successfully" ,
139- nil , // No error during parsing
140- apiError . Raw ,
141- )
123+ var messages [] string
124+ var traverse func ( * xmlquery. Node )
125+ traverse = func ( n * xmlquery. Node ) {
126+ if n . Type == xmlquery . TextNode && strings . TrimSpace ( n . Data ) != "" {
127+ messages = append ( messages , strings . TrimSpace ( n . Data ))
128+ }
129+ for c := n . FirstChild ; c != nil ; c = c . NextSibling {
130+ traverse ( c )
131+ }
142132 }
133+
134+ traverse (doc )
135+
136+ // Concatenate all messages found in the XML for the 'Message' field of APIError
137+ if len (messages ) > 0 {
138+ apiError .Message = strings .Join (messages , "; " )
139+ } else {
140+ // Fallback error message if no specific messages were extracted
141+ apiError .Message = "Failed to extract error details from XML response"
142+ }
143+
144+ // Log the error using the centralized logger
145+ logError (log , apiError , "xml_error_detected" , resp )
143146}
144147
145148// parseTextResponse updates the APIError structure based on a plain text error response and logs it.
0 commit comments