Skip to content

Commit 8ae67b7

Browse files
committed
Update logger method signatures to include 'event' parameter
1 parent 3edd774 commit 8ae67b7

File tree

4 files changed

+69
-83
lines changed

4 files changed

+69
-83
lines changed

httpclient/httpclient_error_response.go

Lines changed: 33 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"net/http"
1010

1111
"github.com/deploymenttheory/go-api-http-client/logger"
12-
"go.uber.org/zap"
1312
)
1413

1514
// APIError represents a more flexible structure for API error responses.
@@ -37,66 +36,51 @@ func (e *APIError) Error() string {
3736

3837
// handleAPIErrorResponse attempts to parse the error response from the API and logs using zap logger.
3938
func handleAPIErrorResponse(resp *http.Response, log logger.Logger) *APIError {
40-
apiError := &APIError{StatusCode: resp.StatusCode}
41-
42-
// Attempt to parse the response into a StructuredError
43-
var structuredErr StructuredError
44-
if err := json.NewDecoder(resp.Body).Decode(&structuredErr); err == nil && structuredErr.Error.Message != "" {
45-
apiError.Type = structuredErr.Error.Code
46-
apiError.Message = structuredErr.Error.Message
47-
48-
// Log the structured error details with zap logger
49-
log.Warn("API returned structured error",
50-
zap.String("error_code", structuredErr.Error.Code),
51-
zap.String("error_message", structuredErr.Error.Message),
52-
zap.Int("status_code", resp.StatusCode),
53-
)
54-
55-
return apiError
39+
// Initialize apiError with the HTTP status code and other fields
40+
apiError := &APIError{
41+
StatusCode: resp.StatusCode,
42+
Type: "APIError", // Default error type
43+
Message: "An error occurred", // Default error message
5644
}
5745

58-
// If the structured error parsing fails, attempt a more generic parsing
46+
// Read the response body
5947
bodyBytes, err := io.ReadAll(resp.Body)
6048
if err != nil {
61-
// If reading the response body fails, store the error message and log the error
62-
apiError.Raw = "Failed to read API error response body"
63-
apiError.Message = err.Error()
64-
apiError.Type = "ReadError"
65-
66-
log.Error("Failed to read API error response body",
67-
zap.Error(err),
68-
)
69-
49+
// Log and return an error if reading the body fails
50+
log.LogError("READ", resp.Request.URL.String(), resp.StatusCode, err, "Failed to read API error response body")
7051
return apiError
7152
}
7253

73-
if err := json.Unmarshal(bodyBytes, &apiError.Errors); err != nil {
74-
// If generic parsing also fails, store the raw response body and log the error
75-
apiError.Raw = string(bodyBytes)
76-
apiError.Message = "Failed to parse API error response"
77-
apiError.Type = "UnexpectedError"
54+
// Attempt to parse the response into a StructuredError
55+
if err := json.Unmarshal(bodyBytes, &apiError); err == nil && apiError.Message != "" {
56+
// Log the structured error with consistency
57+
log.LogError("API", resp.Request.URL.String(), resp.StatusCode, fmt.Errorf(apiError.Message), "")
58+
return apiError
59+
}
7860

79-
log.Error("Failed to parse API error response",
80-
zap.String("raw_response", apiError.Raw),
81-
)
61+
// If structured parsing fails, attempt to parse into a generic error map
62+
var genericErr map[string]interface{}
63+
if err := json.Unmarshal(bodyBytes, &genericErr); err == nil {
64+
// Extract fields from the generic error map and update apiError accordingly
65+
apiError.updateFromGenericError(genericErr)
8266

67+
// Log the error with extracted details consistently
68+
log.LogError("API", resp.Request.URL.String(), resp.StatusCode, fmt.Errorf(apiError.Message), "")
8369
return apiError
8470
}
8571

86-
// Extract fields from the generic error map and log the error with extracted details
87-
if msg, ok := apiError.Errors["message"].(string); ok {
88-
apiError.Message = msg
72+
// If all parsing attempts fail, log the raw response
73+
log.LogError("API", resp.Request.URL.String(), resp.StatusCode, fmt.Errorf("failed to parse API error response"), string(bodyBytes))
74+
return apiError
75+
}
76+
77+
// updateFromGenericError updates the APIError fields based on a generic error map
78+
func (e *APIError) updateFromGenericError(genericErr map[string]interface{}) {
79+
if msg, ok := genericErr["message"].(string); ok {
80+
e.Message = msg
8981
}
90-
if detail, ok := apiError.Errors["detail"].(string); ok {
91-
apiError.Detail = detail
82+
if detail, ok := genericErr["detail"].(string); ok {
83+
e.Detail = detail
9284
}
93-
94-
log.Error("API error",
95-
zap.Int("status_code", apiError.StatusCode),
96-
zap.String("type", apiError.Type),
97-
zap.String("message", apiError.Message),
98-
zap.String("detail", apiError.Detail),
99-
)
100-
101-
return apiError
85+
// Add more fields if necessary
10286
}

httpclient/httpclient_mocklogger.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,26 @@ func (m *MockLogger) GetLogLevel() logger.LogLevel {
6969

7070
// Mock implementations for structured logging methods
7171

72-
func (m *MockLogger) LogRequestStart(requestID string, userID string, method string, url string, headers map[string][]string) {
73-
m.Called(requestID, userID, method, url, headers)
72+
func (m *MockLogger) LogRequestStart(event string, requestID string, userID string, method string, url string, headers map[string][]string) {
73+
m.Called(event, requestID, userID, method, url, headers)
7474
}
7575

76-
func (m *MockLogger) LogRequestEnd(method string, url string, statusCode int, duration time.Duration) {
77-
m.Called(method, url, statusCode, duration)
76+
func (m *MockLogger) LogRequestEnd(event string, method string, url string, statusCode int, duration time.Duration) {
77+
m.Called(event, method, url, statusCode, duration)
7878
}
7979

80-
func (m *MockLogger) LogError(method string, url string, statusCode int, err error, stacktrace string) {
81-
m.Called(method, url, statusCode, err, stacktrace)
80+
func (m *MockLogger) LogError(event string, method string, url string, statusCode int, err error, stacktrace string) {
81+
m.Called(event, method, url, statusCode, err, stacktrace)
8282
}
8383

84-
func (m *MockLogger) LogRetryAttempt(method string, url string, attempt int, reason string, waitDuration time.Duration, err error) {
85-
m.Called(method, url, attempt, reason, waitDuration, err)
84+
func (m *MockLogger) LogRetryAttempt(event string, method string, url string, attempt int, reason string, waitDuration time.Duration, err error) {
85+
m.Called(event, method, url, attempt, reason, waitDuration, err)
8686
}
8787

88-
func (m *MockLogger) LogRateLimiting(method string, url string, retryAfter string, waitDuration time.Duration) {
89-
m.Called(method, url, retryAfter, waitDuration)
88+
func (m *MockLogger) LogRateLimiting(event string, method string, url string, retryAfter string, waitDuration time.Duration) {
89+
m.Called(event, method, url, retryAfter, waitDuration)
9090
}
9191

92-
func (m *MockLogger) LogResponse(method string, url string, statusCode int, responseBody string, responseHeaders map[string][]string, duration time.Duration) {
93-
m.Called(method, url, statusCode, responseBody, responseHeaders, duration)
92+
func (m *MockLogger) LogResponse(event string, method string, url string, statusCode int, responseBody string, responseHeaders map[string][]string, duration time.Duration) {
93+
m.Called(event, method, url, statusCode, responseBody, responseHeaders, duration)
9494
}

logger/zaplogger_logfields.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import (
77
)
88

99
// LogRequestStart logs the initiation of an HTTP request if the current log level permits.
10-
func (d *defaultLogger) LogRequestStart(requestID string, userID string, method string, url string, headers map[string][]string) {
10+
func (d *defaultLogger) LogRequestStart(event string, requestID string, userID string, method string, url string, headers map[string][]string) {
1111
if d.logLevel <= LogLevelInfo {
1212
fields := []zap.Field{
13-
zap.String("event", "request_start"),
13+
zap.String("event", event),
1414
zap.String("method", method),
1515
zap.String("url", url),
1616
zap.String("request_id", requestID),
@@ -22,10 +22,10 @@ func (d *defaultLogger) LogRequestStart(requestID string, userID string, method
2222
}
2323

2424
// LogRequestEnd logs the completion of an HTTP request if the current log level permits.
25-
func (d *defaultLogger) LogRequestEnd(method string, url string, statusCode int, duration time.Duration) {
25+
func (d *defaultLogger) LogRequestEnd(event string, method string, url string, statusCode int, duration time.Duration) {
2626
if d.logLevel <= LogLevelInfo {
2727
fields := []zap.Field{
28-
zap.String("event", "request_end"),
28+
zap.String("event", event),
2929
zap.String("method", method),
3030
zap.String("url", url),
3131
zap.Int("status_code", statusCode),
@@ -35,31 +35,31 @@ func (d *defaultLogger) LogRequestEnd(method string, url string, statusCode int,
3535
}
3636
}
3737

38-
// LogError logs an error that occurs during the processing of an HTTP request if the current log level permits.
39-
func (d *defaultLogger) LogError(method string, url string, statusCode int, err error, stacktrace string) {
38+
// LogError logs an error that occurs during the processing of an HTTP request or any other event, if the current log level permits.
39+
func (d *defaultLogger) LogError(event string, method, url string, statusCode int, err error, stacktrace string) {
4040
if d.logLevel <= LogLevelError {
4141
errorMessage := ""
4242
if err != nil {
4343
errorMessage = err.Error()
4444
}
4545

4646
fields := []zap.Field{
47-
zap.String("event", "request_error"),
47+
zap.String("event", event),
4848
zap.String("method", method),
4949
zap.String("url", url),
5050
zap.Int("status_code", statusCode),
5151
zap.String("error_message", errorMessage),
5252
zap.String("stacktrace", stacktrace),
5353
}
54-
d.logger.Error("Error during HTTP request", fields...)
54+
d.logger.Error("Error occurred", fields...)
5555
}
5656
}
5757

5858
// LogAuthTokenError logs issues encountered during the authentication token acquisition process.
59-
func (d *defaultLogger) LogAuthTokenError(method string, url string, statusCode int, err error) {
59+
func (d *defaultLogger) LogAuthTokenError(event string, method string, url string, statusCode int, err error) {
6060
if d.logLevel <= LogLevelError {
6161
fields := []zap.Field{
62-
zap.String("event", "auth_token_error"),
62+
zap.String("event", event),
6363
zap.String("method", method),
6464
zap.String("url", url),
6565
zap.Int("status_code", statusCode),
@@ -70,10 +70,10 @@ func (d *defaultLogger) LogAuthTokenError(method string, url string, statusCode
7070
}
7171

7272
// LogRetryAttempt logs a retry attempt for an HTTP request if the current log level permits, including wait duration and the error that triggered the retry.
73-
func (d *defaultLogger) LogRetryAttempt(method string, url string, attempt int, reason string, waitDuration time.Duration, err error) {
73+
func (d *defaultLogger) LogRetryAttempt(event string, method string, url string, attempt int, reason string, waitDuration time.Duration, err error) {
7474
if d.logLevel <= LogLevelWarn {
7575
fields := []zap.Field{
76-
zap.String("event", "retry_attempt"),
76+
zap.String("event", event),
7777
zap.String("method", method),
7878
zap.String("url", url),
7979
zap.Int("attempt", attempt),
@@ -86,10 +86,10 @@ func (d *defaultLogger) LogRetryAttempt(method string, url string, attempt int,
8686
}
8787

8888
// LogRateLimiting logs when an HTTP request is rate-limited, including the HTTP method, URL, the value of the 'Retry-After' header, and the actual wait duration.
89-
func (d *defaultLogger) LogRateLimiting(method string, url string, retryAfter string, waitDuration time.Duration) {
89+
func (d *defaultLogger) LogRateLimiting(event string, method string, url string, retryAfter string, waitDuration time.Duration) {
9090
if d.logLevel <= LogLevelWarn {
9191
fields := []zap.Field{
92-
zap.String("event", "rate_limited"),
92+
zap.String("event", event),
9393
zap.String("method", method),
9494
zap.String("url", url),
9595
zap.String("retry_after", retryAfter),
@@ -100,10 +100,10 @@ func (d *defaultLogger) LogRateLimiting(method string, url string, retryAfter st
100100
}
101101

102102
// LogResponse logs details about an HTTP response if the current log level permits.
103-
func (d *defaultLogger) LogResponse(method string, url string, statusCode int, responseBody string, responseHeaders map[string][]string, duration time.Duration) {
103+
func (d *defaultLogger) LogResponse(event string, method string, url string, statusCode int, responseBody string, responseHeaders map[string][]string, duration time.Duration) {
104104
if d.logLevel <= LogLevelInfo {
105105
fields := []zap.Field{
106-
zap.String("event", "response_received"),
106+
zap.String("event", event),
107107
zap.String("method", method),
108108
zap.String("url", url),
109109
zap.Int("status_code", statusCode),

logger/zaplogger_logger.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ type Logger interface {
3131
Panic(msg string, fields ...zapcore.Field)
3232
Fatal(msg string, fields ...zapcore.Field)
3333

34-
LogRequestStart(requestID string, userID string, method string, url string, headers map[string][]string)
35-
LogRequestEnd(method string, url string, statusCode int, duration time.Duration)
36-
LogError(method string, url string, statusCode int, err error, stacktrace string)
37-
LogRetryAttempt(method string, url string, attempt int, reason string, waitDuration time.Duration, err error)
38-
LogRateLimiting(method string, url string, retryAfter string, waitDuration time.Duration)
39-
LogResponse(method string, url string, statusCode int, responseBody string, responseHeaders map[string][]string, duration time.Duration)
34+
// Updated method signatures to include the 'event' parameter
35+
LogRequestStart(event string, requestID string, userID string, method string, url string, headers map[string][]string)
36+
LogRequestEnd(event string, method string, url string, statusCode int, duration time.Duration)
37+
LogError(event string, method string, url string, statusCode int, err error, stacktrace string)
38+
LogAuthTokenError(event string, method string, url string, statusCode int, err error)
39+
LogRetryAttempt(event string, method string, url string, attempt int, reason string, waitDuration time.Duration, err error)
40+
LogRateLimiting(event string, method string, url string, retryAfter string, waitDuration time.Duration)
41+
LogResponse(event string, method string, url string, statusCode int, responseBody string, responseHeaders map[string][]string, duration time.Duration)
4042
}
4143

4244
// GetLogLevel returns the current logging level of the logger. This allows for checking the logger's

0 commit comments

Comments
 (0)