Skip to content

Commit 5cf7cef

Browse files
feat: add raw body to standard errors (#191)
* feat: add raw body to standard errors * use json.RawMessage
1 parent 2f9318b commit 5cf7cef

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

internal/e2e/errors_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func TestStandardErrors(t *testing.T) {
1818
testhelpers.Equals(t, &scw.ResourceNotFound{
1919
Resource: "human",
2020
ResourceID: "b3ba839a-dcf2-4b0a-ac81-fc32370052a0",
21+
RawBody: []byte(`{"message":"resource is not found","resource":"human","resource_id":"b3ba839a-dcf2-4b0a-ac81-fc32370052a0","type":"not_found"}`),
2122
}, err)
2223

2324
_, err = client.CreateHuman(&test.CreateHumanRequest{
@@ -35,6 +36,7 @@ func TestStandardErrors(t *testing.T) {
3536
HelpMessage: "lowest altitude on earth is -6371km",
3637
},
3738
},
39+
RawBody: []byte(`{"details":[{"argument_name":"altitude_in_meter","help_message":"lowest altitude on earth is -6371km","reason":"constraint"}],"message":"invalid argument(s)","type":"invalid_arguments"}`),
3840
}, err)
3941

4042
var human *test.Human
@@ -56,16 +58,19 @@ func TestStandardErrors(t *testing.T) {
5658
Current: 10,
5759
},
5860
},
61+
RawBody: []byte(`{"details":[{"current":10,"quota":10,"resource":"human"}],"message":"quota(s) exceeded for this resource","type":"quotas_exceeded"}`),
5962
}, err)
6063

6164
_, err = client.RunHuman(&test.RunHumanRequest{HumanID: human.ID})
6265
testhelpers.AssertNoError(t, err)
6366

6467
_, err = client.UpdateHuman(&test.UpdateHumanRequest{HumanID: human.ID})
68+
6569
testhelpers.Equals(t, &scw.TransientStateError{
6670
Resource: "human",
6771
ResourceID: human.ID,
6872
CurrentState: "running",
73+
RawBody: []byte(`{"current_state":"running","message":"resource is in a transient state","resource":"human","resource_id":"` + human.ID + `","type":"transient_state"}`),
6974
}, err)
7075

7176
}

scw/errors.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type ResponseError struct {
3535

3636
// Status is the HTTP status received
3737
Status string `json:"-"`
38+
39+
RawBody json.RawMessage `json:"-"`
3840
}
3941

4042
func (e *ResponseError) Error() string {
@@ -77,11 +79,13 @@ func hasResponseError(res *http.Response) SdkError {
7779
if err != nil {
7880
return errors.Wrap(err, "cannot read error response body")
7981
}
82+
newErr.RawBody = body
8083

8184
err = json.Unmarshal(body, newErr)
8285
if err != nil {
8386
return errors.Wrap(err, "could not parse error response body")
8487
}
88+
8589
stdErr := unmarshalStandardError(newErr.Type, body)
8690
if stdErr != nil {
8791
return stdErr
@@ -95,15 +99,15 @@ func unmarshalStandardError(errorType string, body []byte) SdkError {
9599

96100
switch errorType {
97101
case "invalid_arguments":
98-
stdErr = &InvalidArgumentsError{}
102+
stdErr = &InvalidArgumentsError{RawBody: body}
99103
case "quotas_exceeded":
100-
stdErr = &QuotasExceededError{}
104+
stdErr = &QuotasExceededError{RawBody: body}
101105
case "transient_state":
102-
stdErr = &TransientStateError{}
106+
stdErr = &TransientStateError{RawBody: body}
103107
case "not_found":
104-
stdErr = &ResourceNotFound{}
108+
stdErr = &ResourceNotFound{RawBody: body}
105109
case "permissions_denied":
106-
stdErr = &PermissionsDeniedError{}
110+
stdErr = &PermissionsDeniedError{RawBody: body}
107111
default:
108112
return nil
109113
}
@@ -122,6 +126,8 @@ type InvalidArgumentsError struct {
122126
Reason string `json:"reason"`
123127
HelpMessage string `json:"help_message"`
124128
} `json:"details"`
129+
130+
RawBody json.RawMessage `json:"-"`
125131
}
126132

127133
// IsScwSdkError implements the SdkError interface
@@ -154,6 +160,8 @@ type QuotasExceededError struct {
154160
Quota uint32 `json:"quota"`
155161
Current uint32 `json:"current"`
156162
} `json:"details"`
163+
164+
RawBody json.RawMessage `json:"-"`
157165
}
158166

159167
// IsScwSdkError implements the SdkError interface
@@ -172,6 +180,8 @@ type PermissionsDeniedError struct {
172180
Resource string `json:"resource"`
173181
Action string `json:"action"`
174182
} `json:"details"`
183+
184+
RawBody json.RawMessage `json:"-"`
175185
}
176186

177187
// IsScwSdkError implements the SdkError interface
@@ -189,6 +199,8 @@ type TransientStateError struct {
189199
Resource string `json:"resource"`
190200
ResourceID string `json:"resource_id"`
191201
CurrentState string `json:"current_state"`
202+
203+
RawBody json.RawMessage `json:"-"`
192204
}
193205

194206
// IsScwSdkError implements the SdkError interface
@@ -200,6 +212,8 @@ func (e *TransientStateError) Error() string {
200212
type ResourceNotFound struct {
201213
Resource string `json:"resource"`
202214
ResourceID string `json:"resource_id"`
215+
216+
RawBody json.RawMessage `json:"-"`
203217
}
204218

205219
// IsScwSdkError implements the SdkError interface

scw/errors_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ func TestHasResponseErrorWithoutBody(t *testing.T) {
2929
}
3030

3131
func TestHasResponseErrorWithValidError(t *testing.T) {
32-
3332
var (
3433
errorMessage = "some message"
3534
errorType = "some type"
@@ -45,6 +44,7 @@ func TestHasResponseErrorWithValidError(t *testing.T) {
4544
Fields: errorFields,
4645
StatusCode: errorStatusCode,
4746
Status: errorStatus,
47+
RawBody: []byte(`{"message":"some message","type":"some type","fields":{"some_field":["some_value"]}}`),
4848
}
4949

5050
// Create response body with marshalled error response

0 commit comments

Comments
 (0)