Skip to content

Commit e29b7e3

Browse files
authored
fix: parse simple string based errors as part of the response (#1452)
A response can return a payload of the form: ``` { "ok": false, "error": "invalid_blocks", "errors": [ "failed to match all allowed schemas [json-pointer:/blocks/3/text]", "invalid additional property: emoji [json-pointer:/blocks/3/text]" ], "response_metadata": { "messages": [ "[ERROR] failed to match all allowed schemas [json-pointer:/blocks/3/text]", "[ERROR] invalid additional property: emoji [json-pointer:/blocks/3/text]" ] } } ``` This means that we need to fallback to parsing a simple string if we fail to parse the content of "errors" into a `map[string]interface{}`. Closes #1446.
2 parents 13c4aec + a5e465d commit e29b7e3

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

misc.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func (t ConversationsInviteResponseError) Err() error {
4545
type SlackResponseErrors struct {
4646
AppsManifestCreateResponseError *AppsManifestCreateResponseError `json:"-"`
4747
ConversationsInviteResponseError *ConversationsInviteResponseError `json:"-"`
48+
Message *string `json:"-"`
4849
}
4950

5051
// MarshalJSON implements custom marshaling for SlackResponseErrors
@@ -55,6 +56,9 @@ func (e SlackResponseErrors) MarshalJSON() ([]byte, error) {
5556
if e.ConversationsInviteResponseError != nil {
5657
return json.Marshal(e.ConversationsInviteResponseError)
5758
}
59+
if e.Message != nil {
60+
return json.Marshal(*e.Message)
61+
}
5862
return json.Marshal(nil)
5963
}
6064

@@ -67,6 +71,15 @@ func (e *SlackResponseErrors) UnmarshalJSON(data []byte) error {
6771
// Try to determine the error type by checking for unique fields
6872
var raw map[string]interface{}
6973
if err := json.Unmarshal(data, &raw); err != nil {
74+
// If we can't unmarshal as object, try as string (fallback case)
75+
//
76+
// For more details on this specific problem look up issue
77+
// https://github.com/slack-go/slack/issues/1446.
78+
var stringError string
79+
if stringErr := json.Unmarshal(data, &stringError); stringErr == nil {
80+
e.Message = &stringError
81+
return nil
82+
}
7083
return err
7184
}
7285

misc_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ func TestSlackResponseErrorsMarshaling(t *testing.T) {
133133
},
134134
expected: `{"error":"invalid_user","ok":false,"user":"U12345678"}`,
135135
},
136+
{
137+
name: "StringError",
138+
errors: SlackResponseErrors{
139+
Message: func() *string { s := "failed to match all allowed schemas"; return &s }(),
140+
},
141+
expected: `"failed to match all allowed schemas"`,
142+
},
136143
{
137144
name: "EmptyErrors",
138145
errors: SlackResponseErrors{},
@@ -185,6 +192,16 @@ func TestSlackResponseErrorsUnmarshaling(t *testing.T) {
185192
input: `null`,
186193
expected: SlackResponseErrors{},
187194
},
195+
{
196+
name: "StringError",
197+
input: `"failed to match all allowed schemas [json-pointer:\\/blocks\\/3\\/text]"`,
198+
expected: SlackResponseErrors{
199+
Message: func() *string {
200+
s := "failed to match all allowed schemas [json-pointer:\\/blocks\\/3\\/text]"
201+
return &s
202+
}(),
203+
},
204+
},
188205
}
189206

190207
for _, tt := range tests {
@@ -210,6 +227,14 @@ func TestSlackResponseErrorsUnmarshaling(t *testing.T) {
210227
t.Errorf("got %+v; want %+v", *errors.ConversationsInviteResponseError, *tt.expected.ConversationsInviteResponseError)
211228
}
212229
}
230+
231+
if tt.expected.Message != nil {
232+
if errors.Message == nil {
233+
t.Error("expected Message, got nil")
234+
} else if *errors.Message != *tt.expected.Message {
235+
t.Errorf("got %+v; want %+v", *errors.Message, *tt.expected.Message)
236+
}
237+
}
213238
})
214239
}
215240
}
@@ -256,6 +281,28 @@ func TestSlackResponseWithErrors(t *testing.T) {
256281
Ok: true,
257282
},
258283
},
284+
{
285+
name: "ResponseWithStringErrors",
286+
input: `{"ok":false,"error":"invalid_blocks","errors":["failed to match all allowed schemas [json-pointer:\\/blocks\\/3\\/text]","invalid additional property: emoji [json-pointer:\\/blocks\\/3\\/text]"]}`,
287+
expected: SlackResponse{
288+
Ok: false,
289+
Error: "invalid_blocks",
290+
Errors: []SlackResponseErrors{
291+
{
292+
Message: func() *string {
293+
s := "failed to match all allowed schemas [json-pointer:\\/blocks\\/3\\/text]"
294+
return &s
295+
}(),
296+
},
297+
{
298+
Message: func() *string {
299+
s := "invalid additional property: emoji [json-pointer:\\/blocks\\/3\\/text]"
300+
return &s
301+
}(),
302+
},
303+
},
304+
},
305+
},
259306
}
260307

261308
for _, tt := range tests {

0 commit comments

Comments
 (0)