github.com/Files-com/files-sdk-go/v2@v2.1.2/responseerror.go (about) 1 package files_sdk 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/http" 8 "strconv" 9 "time" 10 11 "github.com/Files-com/files-sdk-go/v2/lib" 12 ) 13 14 type ResponseError struct { 15 Type string `json:"type"` 16 Title string `json:"title"` 17 ErrorMessage string `json:"error"` 18 HttpCode int `json:"http-code"` 19 Errors []ResponseError `json:"errors"` 20 Data Data `json:"data"` 21 } 22 23 const ( 24 DestinationExists = "processing-failure/destination-exists" 25 ) 26 27 func IsDestinationExistsError(err error) bool { 28 re, ok := err.(ResponseError) 29 return ok && re.Type == DestinationExists 30 } 31 32 type SignRequest struct { 33 Version string `json:"version"` 34 KeyHandle string `json:"keyHandle"` 35 } 36 37 type U2fSignRequests struct { 38 AppId string `json:"app_id"` 39 Challenge string `json:"challenge"` 40 SignRequest SignRequest `json:"sign_request"` 41 } 42 43 type Data struct { 44 U2fSIgnRequests []U2fSignRequests `json:"u2f_sign_requests,omitempty"` 45 PartialSessionId string `json:"partial_session_id,omitempty"` 46 TwoFactorAuthenticationMethod []string `json:"two_factor_authentication_methods,omitempty"` 47 // Download Request Status 48 BytesTransferred int64 `json:"bytes_transferred"` 49 Status string `json:"status"` 50 StartedAt time.Time `json:"started_at"` 51 CompletedAt time.Time `json:"completed_at"` 52 TouchedAt time.Time `json:"touched_at"` 53 } 54 55 func (e ResponseError) Error() string { 56 return fmt.Sprintf("%v - `%v`", e.Title, e.ErrorMessage) 57 } 58 59 func (e ResponseError) IsNil() bool { 60 return e.ErrorMessage == "" 61 } 62 63 func (e ResponseError) Is(err error) bool { 64 _, ok := err.(ResponseError) 65 66 return ok 67 } 68 69 func (e *ResponseError) UnmarshalJSON(data []byte) error { 70 type re ResponseError 71 var v re 72 err := json.Unmarshal(data, &v) 73 74 if err != nil { 75 jsonError, ok := err.(*json.UnmarshalTypeError) 76 77 if ok && jsonError.Field == "" { 78 if jsonError.Value == "string" { 79 var str string 80 json.Unmarshal(data, &str) 81 v.ErrorMessage = str 82 } else if jsonError.Value != "array" { 83 return err 84 } 85 } else if ok && jsonError.Field == "http-code" { 86 tmp := make(map[string]interface{}) 87 json.Unmarshal(data, &tmp) 88 intVar, _ := strconv.Atoi(tmp["http-code"].(string)) 89 v.HttpCode = intVar 90 } else { 91 return err 92 } 93 94 jsonSyntaxErr, ok := err.(*json.SyntaxError) 95 if ok && jsonSyntaxErr.Error() == "invalid character '<' looking for beginning of value" { 96 return fmt.Errorf(string(data)) 97 } 98 } 99 100 *e = ResponseError(v) 101 return nil 102 } 103 104 func APIError(callbacks ...func(ResponseError) ResponseError) func(res *http.Response) error { 105 return func(res *http.Response) error { 106 if lib.IsNonOkStatus(res) && lib.IsHTML(res) && res.Header.Get("X-Request-Id") != "" && res.Header.Get("Server") == "nginx" { 107 return fmt.Errorf("files.com Server error - request id: %v", res.Header.Get("X-Request-Id")) 108 } 109 110 if lib.IsNonOkStatus(res) && lib.IsJSON(res) { 111 data, err := io.ReadAll(res.Body) 112 if err != nil { 113 return lib.NonOkError(res) 114 } 115 116 re := ResponseError{} 117 118 err = re.UnmarshalJSON(data) 119 if err != nil { 120 return lib.NonOkError(res) 121 } 122 123 if re.IsNil() { 124 return lib.NonOkError(res) 125 } 126 for _, callback := range callbacks { 127 re = callback(re) 128 } 129 return re 130 } 131 return nil 132 } 133 }