X Tutup
Skip to content

Commit 29816b6

Browse files
authored
Merge pull request cli#4862 from cli/api-err-409
api: handle HTTP 409 error message from the server
2 parents 0e3c3bb + ead6bf8 commit 29816b6

File tree

2 files changed

+111
-7
lines changed

2 files changed

+111
-7
lines changed

pkg/cmd/api/api.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -540,36 +540,58 @@ func parseErrorResponse(r io.Reader, statusCode int) (io.Reader, string, error)
540540

541541
var parsedBody struct {
542542
Message string
543-
Errors []json.RawMessage
543+
Errors json.RawMessage
544544
}
545545
err = json.Unmarshal(b, &parsedBody)
546546
if err != nil {
547-
return r, "", err
547+
return bodyCopy, "", err
548+
}
549+
550+
if len(parsedBody.Errors) > 0 && parsedBody.Errors[0] == '"' {
551+
var stringError string
552+
if err := json.Unmarshal(parsedBody.Errors, &stringError); err != nil {
553+
return bodyCopy, "", err
554+
}
555+
if stringError != "" {
556+
if parsedBody.Message != "" {
557+
return bodyCopy, fmt.Sprintf("%s (%s)", stringError, parsedBody.Message), nil
558+
}
559+
return bodyCopy, stringError, nil
560+
}
548561
}
562+
549563
if parsedBody.Message != "" {
550564
return bodyCopy, fmt.Sprintf("%s (HTTP %d)", parsedBody.Message, statusCode), nil
551565
}
552566

553-
type errorMessage struct {
567+
if len(parsedBody.Errors) == 0 || parsedBody.Errors[0] != '[' {
568+
return bodyCopy, "", nil
569+
}
570+
571+
var errorObjects []json.RawMessage
572+
if err := json.Unmarshal(parsedBody.Errors, &errorObjects); err != nil {
573+
return bodyCopy, "", err
574+
}
575+
576+
var objectError struct {
554577
Message string
555578
}
556579
var errors []string
557-
for _, rawErr := range parsedBody.Errors {
580+
for _, rawErr := range errorObjects {
558581
if len(rawErr) == 0 {
559582
continue
560583
}
561584
if rawErr[0] == '{' {
562-
var objectError errorMessage
563585
err := json.Unmarshal(rawErr, &objectError)
564586
if err != nil {
565-
return r, "", err
587+
return bodyCopy, "", err
566588
}
567589
errors = append(errors, objectError.Message)
568590
} else if rawErr[0] == '"' {
569591
var stringError string
570592
err := json.Unmarshal(rawErr, &stringError)
571593
if err != nil {
572-
return r, "", err
594+
return bodyCopy, "", err
573595
}
574596
errors = append(errors, stringError)
575597
}

pkg/cmd/api/api_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,3 +1284,85 @@ func Test_processResponse_template(t *testing.T) {
12841284
`), stdout.String())
12851285
assert.Equal(t, "", stderr.String())
12861286
}
1287+
1288+
func Test_parseErrorResponse(t *testing.T) {
1289+
type args struct {
1290+
input string
1291+
statusCode int
1292+
}
1293+
tests := []struct {
1294+
name string
1295+
args args
1296+
wantErrMsg string
1297+
wantErr bool
1298+
}{
1299+
{
1300+
name: "no error",
1301+
args: args{
1302+
input: `{}`,
1303+
statusCode: 500,
1304+
},
1305+
wantErrMsg: "",
1306+
wantErr: false,
1307+
},
1308+
{
1309+
name: "nil errors",
1310+
args: args{
1311+
input: `{"errors":null}`,
1312+
statusCode: 500,
1313+
},
1314+
wantErrMsg: "",
1315+
wantErr: false,
1316+
},
1317+
{
1318+
name: "simple error",
1319+
args: args{
1320+
input: `{"message": "OH NOES"}`,
1321+
statusCode: 500,
1322+
},
1323+
wantErrMsg: "OH NOES (HTTP 500)",
1324+
wantErr: false,
1325+
},
1326+
{
1327+
name: "errors string",
1328+
args: args{
1329+
input: `{"message": "Conflict", "errors": "Some description"}`,
1330+
statusCode: 409,
1331+
},
1332+
wantErrMsg: "Some description (Conflict)",
1333+
wantErr: false,
1334+
},
1335+
{
1336+
name: "errors array of strings",
1337+
args: args{
1338+
input: `{"errors": ["fail1", "asplode2"]}`,
1339+
statusCode: 500,
1340+
},
1341+
wantErrMsg: "fail1\nasplode2",
1342+
wantErr: false,
1343+
},
1344+
{
1345+
name: "errors array of objects",
1346+
args: args{
1347+
input: `{"errors": [{"message":"fail1"}, {"message":"asplode2"}]}`,
1348+
statusCode: 500,
1349+
},
1350+
wantErrMsg: "fail1\nasplode2",
1351+
wantErr: false,
1352+
},
1353+
}
1354+
for _, tt := range tests {
1355+
t.Run(tt.name, func(t *testing.T) {
1356+
got, got1, err := parseErrorResponse(strings.NewReader(tt.args.input), tt.args.statusCode)
1357+
if (err != nil) != tt.wantErr {
1358+
t.Errorf("parseErrorResponse() error = %v, wantErr %v", err, tt.wantErr)
1359+
}
1360+
if gotString, _ := ioutil.ReadAll(got); tt.args.input != string(gotString) {
1361+
t.Errorf("parseErrorResponse() got = %q, want %q", string(gotString), tt.args.input)
1362+
}
1363+
if got1 != tt.wantErrMsg {
1364+
t.Errorf("parseErrorResponse() got1 = %q, want %q", got1, tt.wantErrMsg)
1365+
}
1366+
})
1367+
}
1368+
}

0 commit comments

Comments
 (0)
X Tutup