@@ -17,12 +17,12 @@ import (
1717
1818// APIError represents an api error response.
1919type APIError struct {
20- StatusCode int `json:"status_code" xml:"StatusCode"` // HTTP status code
21- Type string `json:"type" xml:"Type"` // Type of error
22- Message string `json:"message" xml:"Message"` // Human-readable message
23- Detail string `json:"detail,omitempty" xml:"Detail,omitempty" ` // Detailed error message
24- Errors map [string ]interface {} `json:"errors,omitempty" xml:"Errors,omitempty" ` // Additional error details
25- Raw string `json:"raw" xml:"Raw"` // Raw response body for debugging
20+ StatusCode int `json:"status_code"` // HTTP status code
21+ Type string `json:"type"` // Type of error
22+ Message string `json:"message"` // Human-readable message
23+ Detail string `json:"detail,omitempty"` // Detailed error message
24+ Errors map [string ]interface {} `json:"errors,omitempty"` // Additional error details
25+ Raw string `json:"raw"` // Raw response body for debugging
2626}
2727
2828// Error returns a string representation of the APIError, making it compatible with the error interface.
@@ -46,14 +46,14 @@ func (e *APIError) Error() string {
4646func HandleAPIErrorResponse (resp * http.Response , log logger.Logger ) * APIError {
4747 apiError := & APIError {
4848 StatusCode : resp .StatusCode ,
49- Type : "APIError " ,
49+ Type : "API Error Response " ,
5050 Message : "An error occurred" ,
5151 }
5252
5353 bodyBytes , err := io .ReadAll (resp .Body )
5454 if err != nil {
5555 apiError .Raw = "Failed to read response body"
56- logError ( log , apiError , "error_reading_response_body" , resp )
56+ log . LogError ( "error_reading_response_body" , resp . Request . Method , resp . Request . URL . String (), apiError . StatusCode , resp . Status , err , apiError . Raw )
5757 return apiError
5858 }
5959
@@ -70,7 +70,7 @@ func HandleAPIErrorResponse(resp *http.Response, log logger.Logger) *APIError {
7070 default :
7171 apiError .Raw = string (bodyBytes )
7272 apiError .Message = "Unknown content type error"
73- logError ( log , apiError , "unknown_content_type_error " , resp )
73+ log . LogError ( "unknown_content_type_error" , resp . Request . Method , resp . Request . URL . String (), apiError . StatusCode , "Unknown content type " , nil , apiError . Raw )
7474 }
7575
7676 return apiError
@@ -94,29 +94,27 @@ func ParseContentTypeHeader(header string) (string, map[string]string) {
9494func parseJSONResponse (bodyBytes []byte , apiError * APIError , log logger.Logger , resp * http.Response ) {
9595 if err := json .Unmarshal (bodyBytes , apiError ); err != nil {
9696 apiError .Raw = string (bodyBytes )
97- log .LogError ("json_parsing_error" ,
98- resp .Request .Method ,
99- resp .Request .URL .String (),
100- resp .StatusCode ,
101- "JSON parsing failed" ,
102- err ,
103- apiError .Raw ,
104- )
97+ logError (log , apiError , "json_parsing_error" , resp .Request .Method , resp .Request .URL .String (), resp .Status , err )
10598 } else {
106- // Successfully parsed JSON error, so log the error details.
107- logError (log , apiError , "json_error_detected" , resp )
99+ if apiError .Message == "" {
100+ apiError .Message = "An unknown error occurred"
101+ }
102+
103+ // Log the detected JSON error with all the context information.
104+ logError (log , apiError , "json_error_detected" , resp .Request .Method , resp .Request .URL .String (), resp .Status , nil )
108105 }
109106}
110107
111108// parseXMLResponse dynamically parses XML error responses and accumulates potential error messages.
112109func parseXMLResponse (bodyBytes []byte , apiError * APIError , log logger.Logger , resp * http.Response ) {
113- // Always set the Raw field to the entire XML content for debugging purposes
110+ // Always set the Raw field to the entire XML content for debugging purposes.
114111 apiError .Raw = string (bodyBytes )
115112
116- // Parse the XML document
113+ // Parse the XML document.
117114 doc , err := xmlquery .Parse (bytes .NewReader (bodyBytes ))
118115 if err != nil {
119- logError (log , apiError , "xml_parsing_error" , resp )
116+ // Log the XML parsing error with all the context information.
117+ logError (log , apiError , "xml_parsing_error" , resp .Request .Method , resp .Request .URL .String (), resp .Status , err )
120118 return
121119 }
122120
@@ -133,93 +131,121 @@ func parseXMLResponse(bodyBytes []byte, apiError *APIError, log logger.Logger, r
133131
134132 traverse (doc )
135133
136- // Concatenate all messages found in the XML for the 'Message' field of APIError
134+ // Concatenate all messages found in the XML for the 'Message' field of APIError.
137135 if len (messages ) > 0 {
138136 apiError .Message = strings .Join (messages , "; " )
139137 } else {
140- // Fallback error message if no specific messages were extracted
141138 apiError .Message = "Failed to extract error details from XML response"
142139 }
143140
144- // Log the error using the centralized logger
145- logError (log , apiError , "xml_error_detected" , resp )
141+ // Determine the error to log based on whether a message was found.
142+ var logErr error
143+ if apiError .Message == "" {
144+ logErr = fmt .Errorf ("No error message extracted from XML" )
145+ }
146+
147+ // Log the error or the lack of extracted messages using the centralized logger.
148+ logError (log , apiError , "xml_error_detected" , resp .Request .Method , resp .Request .URL .String (), resp .Status , logErr )
146149}
147150
148151// parseTextResponse updates the APIError structure based on a plain text error response and logs it.
149152func parseTextResponse (bodyBytes []byte , apiError * APIError , log logger.Logger , resp * http.Response ) {
150153 bodyText := string (bodyBytes )
151- apiError .Message = bodyText
152154 apiError .Raw = bodyText
153- // Log the plain text error using the centralized logger.
154- logError (log , apiError , "text_error_detected" , resp )
155+
156+ // Check if the 'Message' field of APIError is empty and use the body text as the message.
157+ if apiError .Message == "" {
158+ apiError .Message = bodyText
159+ }
160+
161+ // Use the updated logError function with the additional parameters.
162+ logError (log , apiError , "text_error_detected" , resp .Request .Method , resp .Request .URL .String (), resp .Status , nil )
155163}
156164
157165// parseHTMLResponse extracts meaningful information from an HTML error response and concatenates all text within <p> tags.
158166func parseHTMLResponse (bodyBytes []byte , apiError * APIError , log logger.Logger , resp * http.Response ) {
159- // Always set the Raw field to the entire HTML content for debugging purposes
167+ // Always set the Raw field to the entire HTML content for debugging purposes.
160168 apiError .Raw = string (bodyBytes )
161169
162170 reader := bytes .NewReader (bodyBytes )
163171 doc , err := html .Parse (reader )
164172 if err != nil {
165- logError (log , apiError , "html_parsing_error" , resp )
173+ // Log HTML parsing error using centralized logger with context.
174+ logError (log , apiError , "html_parsing_error" , resp .Request .Method , resp .Request .URL .String (), resp .Status , err )
166175 return
167176 }
168177
169- var messages []string // To accumulate messages from all <p> tags
178+ var messages []string // To accumulate messages from all <p> tags.
170179 var parse func (* html.Node )
171180 parse = func (n * html.Node ) {
172181 if n .Type == html .ElementNode && n .Data == "p" {
173182 var pText strings.Builder
174183 for c := n .FirstChild ; c != nil ; c = c .NextSibling {
175184 if c .Type == html .TextNode && strings .TrimSpace (c .Data ) != "" {
176- // Build text content of <p> tag
185+ // Build text content of <p> tag.
177186 if pText .Len () > 0 {
178- pText .WriteString (" " ) // Add a space between text nodes within the same <p> tag
187+ pText .WriteString (" " ) // Add a space between text nodes within the same <p> tag.
179188 }
180189 pText .WriteString (strings .TrimSpace (c .Data ))
181190 }
182191 }
183192 if pText .Len () > 0 {
184- // Add the built text content of the <p> tag to messages
193+ // Add the built text content of the <p> tag to messages.
185194 messages = append (messages , pText .String ())
186195 }
187196 }
188197 for c := n .FirstChild ; c != nil ; c = c .NextSibling {
189- parse (c ) // Recursively parse the document
198+ parse (c ) // Recursively parse the document.
190199 }
191200 }
192201
193202 parse (doc )
194203
195- // Concatenate all accumulated messages with a separator
204+ // Concatenate all accumulated messages with a separator.
196205 if len (messages ) > 0 {
197206 apiError .Message = strings .Join (messages , "; " )
198207 } else {
199- // Fallback error message if no specific messages were extracted
208+ // Fallback error message if no specific messages were extracted.
200209 apiError .Message = "HTML Error: See 'Raw' field for details."
201210 }
202211
203- // Log the extracted error message or the fallback message
204- logError (log , apiError , "html_error_detected" , resp )
212+ // Determine the error to log based on whether a message was found.
213+ var logErr error
214+ if apiError .Message == "" {
215+ logErr = fmt .Errorf ("No error message extracted from HTML" )
216+ }
217+
218+ // Log the extracted error message or the fallback message using the centralized logger.
219+ logError (log , apiError , "html_error_detected" , resp .Request .Method , resp .Request .URL .String (), resp .Status , logErr )
205220}
206221
207222// logError logs the error details using the provided logger instance.
208- func logError (log logger.Logger , apiError * APIError , event string , resp * http.Response ) {
223+ // func logError(log logger.Logger, apiError *APIError, event string, resp *http.Response) {
224+ // // Prepare the error message. If apiError.Message is empty, use a default message.
225+ // errorMessage := apiError.Message
226+ // if errorMessage == "" {
227+ // errorMessage = "An unspecified error occurred"
228+ // }
229+
230+ // // Use LogError method from the logger package for error logging.
231+ // log.LogError(
232+ // event,
233+ // resp.Request.Method,
234+ // resp.Request.URL.String(),
235+ // apiError.StatusCode,
236+ // resp.Status,
237+ // fmt.Errorf(errorMessage),
238+ // apiError.Raw,
239+ // )
240+ // }
241+
242+ func logError (log logger.Logger , apiError * APIError , event , method , url , statusMessage string , err error ) {
209243 // Prepare the error message. If apiError.Message is empty, use a default message.
210244 errorMessage := apiError .Message
211245 if errorMessage == "" {
212246 errorMessage = "An unspecified error occurred"
213247 }
214248
215- // Use LogError method from the logger package for error logging.
216- log .LogError (
217- event ,
218- resp .Request .Method ,
219- resp .Request .URL .String (),
220- apiError .StatusCode ,
221- resp .Status ,
222- fmt .Errorf (errorMessage ),
223- apiError .Raw ,
224- )
249+ // Call the LogError method from the logger package for error logging.
250+ log .LogError (event , method , url , apiError .StatusCode , statusMessage , err , apiError .Raw )
225251}
0 commit comments