From a425cc8586708c3315fdf59a51e9b638dc6bcc0d Mon Sep 17 00:00:00 2001 From: Neil Martin Date: Thu, 31 Jul 2025 22:07:36 +0100 Subject: [PATCH 1/2] fix: store raw response in APIError during JSON parsing --- response/error.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/response/error.go b/response/error.go index 15368ea..4ea32c0 100644 --- a/response/error.go +++ b/response/error.go @@ -74,14 +74,15 @@ func HandleAPIErrorResponse(resp *http.Response, sugar *zap.SugaredLogger) *APIE // parseJSONResponse attempts to parse the JSON error response and update the APIError structure. func parseJSONResponse(bodyBytes []byte, apiError *APIError) { + apiError.RawResponse = string(bodyBytes) + if err := json.Unmarshal(bodyBytes, apiError); err != nil { - apiError.RawResponse = string(bodyBytes) } else { if apiError.Message == "" { apiError.Message = "An unknown error occurred" } - } + } // parseXMLResponse dynamically parses XML error responses and accumulates potential error messages. From b706b6823faf13863e42800cd85d2c87a3a68a57 Mon Sep 17 00:00:00 2001 From: Neil Martin Date: Mon, 1 Sep 2025 09:04:53 +0100 Subject: [PATCH 2/2] fix: add additional fields to APIError struct for Jamf Pro JSON error responses --- response/error.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/response/error.go b/response/error.go index 4ea32c0..62040b4 100644 --- a/response/error.go +++ b/response/error.go @@ -17,14 +17,24 @@ import ( // APIError represents an api error response. type APIError struct { - StatusCode int `json:"status_code"` // HTTP status code - Method string `json:"method"` // HTTP method used for the request - URL string `json:"url"` // The URL of the HTTP request + StatusCode int `json:"status_code"` // HTTP status code + Method string `json:"method"` // HTTP method used for the request + URL string `json:"url"` // The URL of the HTTP request + HTTPStatus int `json:"httpStatus,omitempty"` + Errors []Errors `json:"errors,omitempty"` Message string `json:"message"` // Summary of the error Details []string `json:"details,omitempty"` // Detailed error messages, if any RawResponse string `json:"raw_response"` // Raw response body for debugging } +// Errors represents individual error details within an API error response. +type Errors struct { + Code string `json:"code,omitempty"` + Field string `json:"field,omitempty"` + Description string `json:"description,omitempty"` + ID *string `json:"id,omitempty"` +} + // Error returns a string representation of the APIError, making it compatible with the error interface. func (e *APIError) Error() string { data, err := json.Marshal(e) @@ -74,15 +84,14 @@ func HandleAPIErrorResponse(resp *http.Response, sugar *zap.SugaredLogger) *APIE // parseJSONResponse attempts to parse the JSON error response and update the APIError structure. func parseJSONResponse(bodyBytes []byte, apiError *APIError) { - apiError.RawResponse = string(bodyBytes) - if err := json.Unmarshal(bodyBytes, apiError); err != nil { + apiError.RawResponse = string(bodyBytes) } else { if apiError.Message == "" { apiError.Message = "An unknown error occurred" } - } + } } // parseXMLResponse dynamically parses XML error responses and accumulates potential error messages.