1 package bunny
2 3 import (
4 "fmt"
5 "net/http"
6 "strings"
7 )
8 9 // HTTPError is returned by the Client when an unsuccessful HTTP response was
10 // returned or a response could not be processed.
11 // If the body of an unsuccessful HTTP response contains an APIError in the
12 // body, APIError is returned by the Client instead.
13 type HTTPError struct {
14 // RequestURL is the address to which the request was sent that caused the error.
15 RequestURL string
16 // The HTTP response status code.
17 StatusCode int
18 // The raw http response body. It's nil if the response had no body or it could not be received.
19 RespBody []byte
20 // Errors contain errors that happened while receiving or processing the HTTP response.
21 Errors []error
22 }
23 24 // Error returns a textual representation of the error.
25 func (e *HTTPError) Error() string {
26 var res strings.Builder
27 28 res.WriteString(fmt.Sprintf("http-request to %s failed: %s (%d)",
29 e.RequestURL, http.StatusText(e.StatusCode), e.StatusCode,
30 ))
31 32 if len(e.Errors) > 0 {
33 res.WriteString(", errors: " + strings.Join(errorsToStrings(e.Errors), ", "))
34 }
35 36 return res.String()
37 }
38 39 func errorsToStrings(errs []error) []string {
40 res := make([]string, 0, len(errs))
41 42 for _, err := range errs {
43 res = append(res, err.Error())
44 }
45 46 return res
47 }
48 49 // AuthenticationError represents an Unauthorized (401) HTTP error.
50 type AuthenticationError struct {
51 Message string
52 }
53 54 // Error returns a textual representation of the error.
55 func (e *AuthenticationError) Error() string {
56 return e.Message
57 }
58 59 // APIError represents an error that is returned by some Bunny API endpoints on
60 // failures.
61 type APIError struct {
62 HTTPError
63 64 ErrorKey string `json:"ErrorKey"`
65 Field string `json:"Field"`
66 Message string `json:"Message"`
67 }
68 69 // Error returns the string representation of the error.
70 // ErrorKey, Field and Message are omitted if they are empty.
71 func (e *APIError) Error() string {
72 var res strings.Builder
73 74 res.WriteString(e.HTTPError.Error())
75 76 if e.ErrorKey != "" {
77 res.WriteString(", ")
78 res.WriteString(e.ErrorKey)
79 80 if e.Field != "" {
81 res.WriteString(": ")
82 res.WriteString(e.Field)
83 }
84 } else if e.Field != "" {
85 res.WriteString(", ")
86 res.WriteString(e.Field)
87 }
88 89 if e.Message != "" {
90 // Field and ErrorKey contains the same information then Message, no need to log them.
91 res.WriteString(", ")
92 res.WriteString(e.Message)
93 }
94 95 return res.String()
96 }
97