Less obtuse error handling from API responses

This commit is contained in:
Dane Everitt 2019-12-16 20:34:58 -08:00
parent a1fa876734
commit 514c16ccc8
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
4 changed files with 31 additions and 35 deletions

View File

@ -2,8 +2,8 @@ package api
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"github.com/buger/jsonparser"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"go.uber.org/zap" "go.uber.org/zap"
@ -24,12 +24,6 @@ type PanelRequest struct {
Response *http.Response Response *http.Response
} }
func IsRequestError (err error) bool {
_, ok := err.(*PanelRequest)
return ok
}
// Builds the base request instance that can be used with the HTTP client. // Builds the base request instance that can be used with the HTTP client.
func (r *PanelRequest) GetClient() *http.Client { func (r *PanelRequest) GetClient() *http.Client {
return &http.Client{Timeout: time.Second * 30} return &http.Client{Timeout: time.Second * 30}
@ -116,29 +110,34 @@ func (r *PanelRequest) HttpResponseCode() int {
return r.Response.StatusCode return r.Response.StatusCode
} }
type RequestError struct {
Code string `json:"code"`
Status string `json:"status"`
Detail string `json:"detail"`
}
// Returns the error response in a string form that can be more easily consumed.
func (re *RequestError) String() string {
return fmt.Sprintf("%s: %s (HTTP/%s)", re.Code, re.Detail, re.Status)
}
type RequestErrorBag struct {
Errors []RequestError `json:"errors"`
}
// Returns the error message from the API call as a string. The error message will be formatted // Returns the error message from the API call as a string. The error message will be formatted
// similar to the below example: // similar to the below example:
// //
// HttpNotFoundException: The requested resource does not exist. (HTTP/404) // HttpNotFoundException: The requested resource does not exist. (HTTP/404)
func (r *PanelRequest) Error() string { func (r *PanelRequest) Error() *RequestError {
body, err := r.ReadBody() body, _ := r.ReadBody()
if err != nil {
return err.Error() bag := RequestErrorBag{}
json.Unmarshal(body, &bag)
if len(bag.Errors) == 0 {
return new(RequestError)
} }
zap.S().Debugw("got body", zap.ByteString("b", body)) return &bag.Errors[0]
_, valueType, _, err := jsonparser.Get(body, "errors")
if err != nil {
return err.Error()
}
if valueType != jsonparser.Object {
return "no error object present on response"
}
code, _ := jsonparser.GetString(body, "errors.0.code")
status, _ := jsonparser.GetString(body, "errors.0.status")
detail, _ := jsonparser.GetString(body, "errors.0.detail")
return fmt.Sprintf("%s: %s (HTTP/%s)", code, detail, status)
} }

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/parser" "github.com/pterodactyl/wings/parser"
"go.uber.org/zap"
) )
const ( const (
@ -40,9 +39,7 @@ func (r *PanelRequest) GetServerConfiguration(uuid string) (*ServerConfiguration
r.Response = resp r.Response = resp
if r.HasError() { if r.HasError() {
zap.S().Warnw("got error", zap.String("message", r.Error())) return nil, errors.WithStack(errors.New(r.Error().String()))
return nil, errors.WithStack(errors.New(r.Error()))
} }
res := &ServerConfiguration{} res := &ServerConfiguration{}

View File

@ -25,7 +25,7 @@ func (r *PanelRequest) ValidateSftpCredentials(request sftp_server.Authenticatio
return nil, sftp_server.InvalidCredentialsError{} return nil, sftp_server.InvalidCredentialsError{}
} }
return nil, errors.WithStack(errors.New(r.Error())) return nil, errors.WithStack(errors.New(r.Error().String()))
} }
response := new(sftp_server.AuthenticationResponse) response := new(sftp_server.AuthenticationResponse)

View File

@ -173,13 +173,13 @@ func LoadDirectory(dir string, cfg *config.SystemConfiguration) error {
b, err := ioutil.ReadFile(path.Join(dir, file.Name())) b, err := ioutil.ReadFile(path.Join(dir, file.Name()))
if err != nil { if err != nil {
zap.S().Errorw("failed to read server configuration file, skipping...", zap.Error(err)) zap.S().Errorw("failed to read server configuration file, skipping...", zap.String("server", file.Name()), zap.Error(err))
return return
} }
s, err := FromConfiguration(b, cfg) s, err := FromConfiguration(b, cfg)
if err != nil { if err != nil {
zap.S().Errorw("failed to parse server configuration, skipping...", zap.Error(err)) zap.S().Errorw("failed to parse server configuration, skipping...", zap.String("server", file.Name()), zap.Error(err))
return return
} }