Skip to content

Commit ba69896

Browse files
committed
Refactor error handling and parsing in response package
1 parent a6197e5 commit ba69896

File tree

3 files changed

+37
-202
lines changed

3 files changed

+37
-202
lines changed

response/error.go

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ import (
1717

1818
// APIError represents an api error response.
1919
type APIError struct {
20-
StatusCode int `json:"status_code"` // HTTP status code
21-
Method string `json:"method"` // HTTP method used for the request
22-
URL string `json:"url"` // The URL of the HTTP request
23-
Message string `json:"message"` // Summary of the error
24-
Details []string `json:"details"` // Detailed error messages, if any
25-
RawResponse string `json:"raw_response"` // Raw response body for debugging
20+
StatusCode int `json:"status_code"` // HTTP status code
21+
Method string `json:"method"` // HTTP method used for the request
22+
URL string `json:"url"` // The URL of the HTTP request
23+
Message string `json:"message"` // Summary of the error
24+
Details []string `json:"details,omitempty"` // Detailed error messages, if any
25+
RawResponse string `json:"raw_response"` // Raw response body for debugging
2626
}
2727

2828
// Error returns a string representation of the APIError, making it compatible with the error interface.
@@ -166,59 +166,71 @@ func parseTextResponse(bodyBytes []byte, apiError *APIError, log logger.Logger,
166166
)
167167
}
168168

169-
// parseHTMLResponse extracts meaningful information from an HTML error response and concatenates all text within <p> tags.
169+
// parseHTMLResponse extracts meaningful information from an HTML error response,
170+
// concatenating all text within <p> tags and links found within them.
170171
func parseHTMLResponse(bodyBytes []byte, apiError *APIError, log logger.Logger, resp *http.Response) {
171-
// Always set the Raw field to the entire HTML content for debugging purposes.
172+
// Set the entire HTML content as the RawResponse for debugging purposes.
172173
apiError.RawResponse = string(bodyBytes)
173174

175+
// Parse the HTML document.
174176
reader := bytes.NewReader(bodyBytes)
175177
doc, err := html.Parse(reader)
176178
if err != nil {
177179
log.LogError("html_parsing_error", resp.Request.Method, resp.Request.URL.String(), apiError.StatusCode, resp.Status, err, apiError.RawResponse)
178180
return
179181
}
180182

181-
var messages []string // To accumulate messages from all <p> tags.
183+
var messages []string // To accumulate messages and links.
182184
var parse func(*html.Node)
183185
parse = func(n *html.Node) {
184186
if n.Type == html.ElementNode && n.Data == "p" {
185-
var pText strings.Builder
187+
var pContent strings.Builder
186188
for c := n.FirstChild; c != nil; c = c.NextSibling {
187-
if c.Type == html.TextNode && strings.TrimSpace(c.Data) != "" {
188-
// Build text content of <p> tag.
189-
if pText.Len() > 0 {
190-
pText.WriteString(" ") // Add a space between text nodes within the same <p> tag.
189+
if c.Type == html.TextNode {
190+
// Append text content directly.
191+
pContent.WriteString(strings.TrimSpace(c.Data) + " ")
192+
} else if c.Type == html.ElementNode && c.Data == "a" {
193+
// Extract href attribute value for links.
194+
var href string
195+
for _, attr := range c.Attr {
196+
if attr.Key == "href" {
197+
href = attr.Val
198+
break
199+
}
200+
}
201+
if href != "" {
202+
// Append the link to the pContent builder.
203+
pContent.WriteString(fmt.Sprintf("[Link: %s] ", href))
191204
}
192-
pText.WriteString(strings.TrimSpace(c.Data))
193205
}
194206
}
195-
if pText.Len() > 0 {
196-
// Add the built text content of the <p> tag to messages.
197-
messages = append(messages, pText.String())
207+
finalContent := strings.TrimSpace(pContent.String())
208+
if finalContent != "" {
209+
// Add the content of the <p> tag to messages.
210+
messages = append(messages, finalContent)
198211
}
199212
}
200213
for c := n.FirstChild; c != nil; c = c.NextSibling {
201-
parse(c) // Recursively parse the document.
214+
parse(c) // Continue traversing the document.
202215
}
203216
}
204217

205-
parse(doc)
218+
parse(doc) // Start parsing the document.
206219

207-
// Concatenate all accumulated messages with a separator.
220+
// Concatenate all accumulated messages and links with a separator.
208221
if len(messages) > 0 {
209222
apiError.Message = strings.Join(messages, "; ")
210223
} else {
211-
// Fallback error message if no specific messages were extracted.
224+
// Fallback error message if no specific content was extracted.
212225
apiError.Message = "HTML Error: See 'Raw' field for details."
213226
}
214227

215-
// Determine the error to log based on whether a message was found.
228+
// Determine the error to log based on whether content was found.
216229
var logErr error
217230
if apiError.Message == "" {
218231
logErr = fmt.Errorf("no error message extracted from HTML")
219232
}
220233

221-
// Log the extracted error message or the fallback message using the centralized logger.
234+
// Log the extracted content or the fallback message using the centralized logger.
222235
log.LogError("html_error_detected", resp.Request.Method, resp.Request.URL.String(), apiError.StatusCode, resp.Status, logErr, apiError.RawResponse)
223-
224236
}

response/error.go.back

Lines changed: 0 additions & 177 deletions
This file was deleted.
File renamed without changes.

0 commit comments

Comments
 (0)