Skip to content

Commit 5ff34b0

Browse files
authored
feat: add support for out of stock error (#190)
1 parent 1a5dc47 commit 5ff34b0

File tree

2 files changed

+99
-55
lines changed

2 files changed

+99
-55
lines changed

internal/e2e/errors_test.go

Lines changed: 81 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,65 +12,95 @@ func TestStandardErrors(t *testing.T) {
1212
client, _, err := newE2EClient(true)
1313
testhelpers.AssertNoError(t, err)
1414

15-
_, err = client.GetHuman(&test.GetHumanRequest{
16-
HumanID: "b3ba839a-dcf2-4b0a-ac81-fc32370052a0",
15+
t.Run("not found", func(t *testing.T) {
16+
_, err = client.GetHuman(&test.GetHumanRequest{
17+
HumanID: "b3ba839a-dcf2-4b0a-ac81-fc32370052a0",
18+
})
19+
testhelpers.Equals(t, &scw.ResourceNotFoundError{
20+
Resource: "human",
21+
ResourceID: "b3ba839a-dcf2-4b0a-ac81-fc32370052a0",
22+
RawBody: []byte(`{"message":"resource is not found","resource":"human","resource_id":"b3ba839a-dcf2-4b0a-ac81-fc32370052a0","type":"not_found"}`),
23+
}, err)
1724
})
18-
testhelpers.Equals(t, &scw.ResourceNotFound{
19-
Resource: "human",
20-
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"}`),
22-
}, err)
2325

24-
_, err = client.CreateHuman(&test.CreateHumanRequest{
25-
AltitudeInMeter: -7000000,
26-
})
27-
testhelpers.Equals(t, &scw.InvalidArgumentsError{
28-
Details: []struct {
29-
ArgumentName string `json:"argument_name"`
30-
Reason string `json:"reason"`
31-
HelpMessage string `json:"help_message"`
32-
}{
33-
{
34-
ArgumentName: "altitude_in_meter",
35-
Reason: "constraint",
36-
HelpMessage: "lowest altitude on earth is -6371km",
26+
t.Run("invalid argument", func(t *testing.T) {
27+
_, err = client.CreateHuman(&test.CreateHumanRequest{
28+
AltitudeInMeter: -7000000,
29+
})
30+
testhelpers.Equals(t, &scw.InvalidArgumentsError{
31+
Details: []struct {
32+
ArgumentName string `json:"argument_name"`
33+
Reason string `json:"reason"`
34+
HelpMessage string `json:"help_message"`
35+
}{
36+
{
37+
ArgumentName: "altitude_in_meter",
38+
Reason: "constraint",
39+
HelpMessage: "lowest altitude on earth is -6371km",
40+
},
3741
},
38-
},
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"}`),
40-
}, err)
42+
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"}`),
43+
}, err)
44+
})
4145

42-
var human *test.Human
43-
for i := 0; i < 10; i++ {
44-
human, err = client.CreateHuman(&test.CreateHumanRequest{})
45-
testhelpers.AssertNoError(t, err)
46-
}
46+
t.Run("quotas exceeded", func(t *testing.T) {
47+
var humans []*test.Human
4748

48-
_, err = client.CreateHuman(&test.CreateHumanRequest{})
49-
testhelpers.Equals(t, &scw.QuotasExceededError{
50-
Details: []struct {
51-
Resource string `json:"resource"`
52-
Quota uint32 `json:"quota"`
53-
Current uint32 `json:"current"`
54-
}{
55-
{
56-
Resource: "human",
57-
Quota: 10,
58-
Current: 10,
49+
for i := 0; i < 10; i++ {
50+
human, err := client.CreateHuman(&test.CreateHumanRequest{})
51+
testhelpers.AssertNoError(t, err)
52+
humans = append(humans, human)
53+
}
54+
55+
_, err = client.CreateHuman(&test.CreateHumanRequest{})
56+
testhelpers.Equals(t, &scw.QuotasExceededError{
57+
Details: []struct {
58+
Resource string `json:"resource"`
59+
Quota uint32 `json:"quota"`
60+
Current uint32 `json:"current"`
61+
}{
62+
{
63+
Resource: "human",
64+
Quota: 10,
65+
Current: 10,
66+
},
5967
},
60-
},
61-
RawBody: []byte(`{"details":[{"current":10,"quota":10,"resource":"human"}],"message":"quota(s) exceeded for this resource","type":"quotas_exceeded"}`),
62-
}, err)
68+
RawBody: []byte(`{"details":[{"current":10,"quota":10,"resource":"human"}],"message":"quota(s) exceeded for this resource","type":"quotas_exceeded"}`),
69+
}, err)
6370

64-
_, err = client.RunHuman(&test.RunHumanRequest{HumanID: human.ID})
65-
testhelpers.AssertNoError(t, err)
71+
for _, human := range humans {
72+
_, err := client.DeleteHuman(&test.DeleteHumanRequest{HumanID: human.ID})
73+
testhelpers.AssertNoError(t, err)
74+
}
75+
})
6676

67-
_, err = client.UpdateHuman(&test.UpdateHumanRequest{HumanID: human.ID})
77+
t.Run("transient state", func(t *testing.T) {
78+
human, err := client.CreateHuman(&test.CreateHumanRequest{})
79+
testhelpers.AssertNoError(t, err)
80+
defer func() {
81+
_, _ = client.DeleteHuman(&test.DeleteHumanRequest{HumanID: human.ID})
82+
}()
83+
84+
_, err = client.RunHuman(&test.RunHumanRequest{HumanID: human.ID})
85+
testhelpers.AssertNoError(t, err)
6886

69-
testhelpers.Equals(t, &scw.TransientStateError{
70-
Resource: "human",
71-
ResourceID: human.ID,
72-
CurrentState: "running",
73-
RawBody: []byte(`{"current_state":"running","message":"resource is in a transient state","resource":"human","resource_id":"` + human.ID + `","type":"transient_state"}`),
74-
}, err)
87+
_, err = client.UpdateHuman(&test.UpdateHumanRequest{HumanID: human.ID})
88+
testhelpers.Equals(t, &scw.TransientStateError{
89+
Resource: "human",
90+
ResourceID: human.ID,
91+
CurrentState: "running",
92+
RawBody: []byte(`{"current_state":"running","message":"resource is in a transient state","resource":"human","resource_id":"` + human.ID + `","type":"transient_state"}`),
93+
}, err)
7594

95+
})
96+
97+
t.Run("out of stock", func(t *testing.T) {
98+
_, err = client.CreateHuman(&test.CreateHumanRequest{
99+
ShoeSize: 60,
100+
})
101+
testhelpers.Equals(t, &scw.OutOfStockError{
102+
Resource: "ShoeSize60",
103+
RawBody: []byte(`{"message":"resource is out of stock","resource":"ShoeSize60","type":"out_of_stock"}`),
104+
}, err)
105+
})
76106
}

scw/errors.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,11 @@ func unmarshalStandardError(errorType string, body []byte) SdkError {
105105
case "transient_state":
106106
stdErr = &TransientStateError{RawBody: body}
107107
case "not_found":
108-
stdErr = &ResourceNotFound{RawBody: body}
108+
stdErr = &ResourceNotFoundError{RawBody: body}
109109
case "permissions_denied":
110110
stdErr = &PermissionsDeniedError{RawBody: body}
111+
case "out_of_stock":
112+
stdErr = &OutOfStockError{RawBody: body}
111113
default:
112114
return nil
113115
}
@@ -209,15 +211,27 @@ func (e *TransientStateError) Error() string {
209211
return fmt.Sprintf("scaleway-sdk-go: resource %s with ID %s is in a transient state: %s", e.Resource, e.ResourceID, e.CurrentState)
210212
}
211213

212-
type ResourceNotFound struct {
214+
type ResourceNotFoundError struct {
213215
Resource string `json:"resource"`
214216
ResourceID string `json:"resource_id"`
215217

216218
RawBody json.RawMessage `json:"-"`
217219
}
218220

219221
// IsScwSdkError implements the SdkError interface
220-
func (e *ResourceNotFound) IsScwSdkError() {}
221-
func (e *ResourceNotFound) Error() string {
222+
func (e *ResourceNotFoundError) IsScwSdkError() {}
223+
func (e *ResourceNotFoundError) Error() string {
222224
return fmt.Sprintf("scaleway-sdk-go: resource %s with ID %s is not found", e.Resource, e.ResourceID)
223225
}
226+
227+
type OutOfStockError struct {
228+
Resource string `json:"resource"`
229+
230+
RawBody json.RawMessage `json:"-"`
231+
}
232+
233+
// IsScwSdkError implements the SdkError interface
234+
func (e *OutOfStockError) IsScwSdkError() {}
235+
func (e *OutOfStockError) Error() string {
236+
return fmt.Sprintf("scaleway-sdk-go: resource %s is out of stock", e.Resource)
237+
}

0 commit comments

Comments
 (0)