Skip to content

Commit aec7c2b

Browse files
committed
feat(common): Client with conditional err handling
1 parent d252220 commit aec7c2b

1 file changed

Lines changed: 32 additions & 7 deletions

File tree

common/http.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,26 @@ type ErrorHandler func(rsp *http.Response, body []byte) error
110110

111111
type ResponseHandler func(rsp *http.Response) (*http.Response, error)
112112

113-
// HTTPClient is an HTTP client that handles OAuth access token refreshes.
113+
// ShouldHandleError determines whether the default or custom ErrorHandler
114+
// should be invoked for a given HTTP response.
115+
// Returning true indicates that the response represents an error that requires handling.
116+
type ShouldHandleError func(response *http.Response) bool
117+
118+
// HTTPClient is an HTTP client that handles OAuth access token refreshes
119+
// and provides hooks for custom error and response handling.
114120
type HTTPClient struct {
115-
Base string // optional base URL. If not set, then all URLs must be absolute.
116-
Client AuthenticatedHTTPClient // underlying HTTP client. Required.
117-
ErrorHandler ErrorHandler // optional error handler. If not set, then the default error handler is used.
118-
ResponseHandler ResponseHandler // optional, Allows mutation of the http.Response from the Saas API response.
121+
// [Deprecated] URL endpoints are not the responsibility of HTTPClient.
122+
// NOTE: to avoid linter errors the deprecation comment is not of correct golang formatting.
123+
// Optional base URL. If unset, all request URLs must be absolute.
124+
Base string
125+
// Underlying HTTP client. Required.
126+
Client AuthenticatedHTTPClient
127+
// Optional ErrorHandler. If not set, then the default error handler is used.
128+
ErrorHandler ErrorHandler
129+
// Optional ResponseHandler, allowing mutation of the http.Response returned by the SaaS API.
130+
ResponseHandler ResponseHandler
131+
// Optional predicate deciding whether the ErrorHandler should be invoked.
132+
ShouldHandleError ShouldHandleError
119133
}
120134

121135
// getURL returns the base prefixed URL.
@@ -597,15 +611,26 @@ func (h *HTTPClient) sendRequest(req *http.Request) (*http.Response, []byte, err
597611
return nil, nil, fmt.Errorf("error reading response body: %w", err)
598612
}
599613

600-
// Check the response status code
601-
if res.StatusCode < 200 || res.StatusCode > 299 {
614+
shouldHandleError := h.ShouldHandleError
615+
if shouldHandleError == nil {
616+
// Default predicate: treat "non-2xx" responses as requiring error handling.
617+
shouldHandleError = func(response *http.Response) bool {
618+
return response.StatusCode < 200 || response.StatusCode > 299
619+
}
620+
}
621+
622+
if shouldHandleError(res) {
602623
if h.ErrorHandler != nil {
624+
// Invoke the custom error handler.
603625
return res, body, h.ErrorHandler(res, body)
604626
}
605627

628+
// Fallback to generic error interpretation.
606629
return res, body, InterpretError(res, body)
607630
}
608631

632+
// Response may indicate a logical failure at the API level (e.g., a record-level error),
633+
// but it is not a fatal HTTP error. Connectors can handle it according to their contract.
609634
return res, body, nil
610635
}
611636

0 commit comments

Comments
 (0)