mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-24 20:38:34 +00:00
fix(api): improve API response error handling (#2043)
Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
09e3cd62b7
commit
2c3f0c5578
@ -334,11 +334,22 @@ func validateResponseCode(res *http.Response) error {
|
|||||||
errRes := &ErrorResponseBody{}
|
errRes := &ErrorResponseBody{}
|
||||||
|
|
||||||
err := json.NewDecoder(res.Body).Decode(errRes)
|
err := json.NewDecoder(res.Body).Decode(errRes)
|
||||||
if err == nil && errRes.Errors != nil {
|
if err == nil {
|
||||||
var errList []string
|
var errList []string
|
||||||
|
|
||||||
for k, v := range *errRes.Errors {
|
if errRes.Errors != nil {
|
||||||
errList = append(errList, fmt.Sprintf("%s: %s", k, strings.TrimRight(v, "\n\r")))
|
for k, v := range *errRes.Errors {
|
||||||
|
errList = append(errList, fmt.Sprintf("%s: %s", k, strings.TrimRight(v, "\n\r")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if errRes.Message != nil && *errRes.Message != "" {
|
||||||
|
split := slices.Compact(strings.Split(*errRes.Message, "\n"))
|
||||||
|
// skip empty lines and the first line, which is a duplicate of the HTTP status message
|
||||||
|
split = slices.DeleteFunc(split, func(s string) bool {
|
||||||
|
return len(s) == 0 || strings.HasPrefix(s, msg)
|
||||||
|
})
|
||||||
|
errList = append(errList, split...)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = fmt.Sprintf("%s (%s)", msg, strings.Join(errList, " - "))
|
msg = fmt.Sprintf("%s (%s)", msg, strings.Join(errList, " - "))
|
||||||
|
@ -9,6 +9,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -53,6 +54,7 @@ func TestClientDoRequest(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
status string
|
status string
|
||||||
|
body string
|
||||||
wantErr error
|
wantErr error
|
||||||
}{
|
}{
|
||||||
{name: "no error", status: "200 OK", wantErr: nil},
|
{name: "no error", status: "200 OK", wantErr: nil},
|
||||||
@ -62,6 +64,15 @@ func TestClientDoRequest(t *testing.T) {
|
|||||||
Code: 500,
|
Code: 500,
|
||||||
Message: "Internal Server Error",
|
Message: "Internal Server Error",
|
||||||
}},
|
}},
|
||||||
|
{
|
||||||
|
name: "500 status with body",
|
||||||
|
status: "500 create sdn zone object failed: 400 Parameter verification failed.",
|
||||||
|
body: `{"message":"create sdn zone object failed: 400 Parameter verification failed.\nipam: ipam-simple not existing\n","data":null}`,
|
||||||
|
wantErr: &HTTPError{
|
||||||
|
Code: 500,
|
||||||
|
Message: "create sdn zone object failed: 400 Parameter verification failed. (ipam: ipam-simple not existing)",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -77,7 +88,7 @@ func TestClientDoRequest(t *testing.T) {
|
|||||||
return &http.Response{
|
return &http.Response{
|
||||||
Status: tt.status,
|
Status: tt.status,
|
||||||
StatusCode: sc,
|
StatusCode: sc,
|
||||||
Body: nil,
|
Body: io.NopCloser(strings.NewReader(tt.body)),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
@ -20,8 +20,9 @@ type MultiPartData struct {
|
|||||||
|
|
||||||
// ErrorResponseBody contains the body of an error response.
|
// ErrorResponseBody contains the body of an error response.
|
||||||
type ErrorResponseBody struct {
|
type ErrorResponseBody struct {
|
||||||
Data *string `json:"data"`
|
Data *string `json:"data"`
|
||||||
Errors *map[string]string `json:"errors"`
|
Message *string `json:"message"`
|
||||||
|
Errors *map[string]string `json:"errors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileUploadRequest is a request for uploading a file.
|
// FileUploadRequest is a request for uploading a file.
|
||||||
|
Loading…
Reference in New Issue
Block a user