-
Notifications
You must be signed in to change notification settings - Fork 0
/
error.go
136 lines (115 loc) · 3.76 KB
/
error.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"encoding/json"
"fmt"
"net/http"
"strings"
bimg "gopkg.in/h2non/bimg.v1"
)
const (
_ uint8 = iota
BadRequest
NotAllowed
Unsupported
Unauthorized
InternalError
NotFound
NotImplemented
Forbidden
NotAcceptable
)
var (
ErrNotFound = NewError("not found", NotFound)
ErrInvalidAPIKey = NewError("invalid or missing API key", Unauthorized)
ErrMethodNotAllowed = NewError("method not allowed", NotAllowed)
ErrUnsupportedMedia = NewError("unsupported media type", Unsupported)
ErrOutputFormat = NewError("unsupported output image format", BadRequest)
ErrEmptyBody = NewError("empty image", BadRequest)
ErrMissingParamFile = NewError("missing required param: file", BadRequest)
ErrInvalidFilePath = NewError("invalid file path", BadRequest)
ErrInvalidImageURL = NewError("invalid image URL", BadRequest)
ErrMissingImageSource = NewError("cannot process the image due to missing or invalid params", BadRequest)
ErrNotImplemented = NewError("not implemented endpoint", NotImplemented)
ErrInvalidURLSignature = NewError("invalid URL signature", BadRequest)
ErrURLSignatureMismatch = NewError("URL signature mismatch", Forbidden)
)
type Error struct {
Message string `json:"message,omitempty"`
Code uint8 `json:"code"`
}
func (e Error) JSON() []byte {
buf, _ := json.Marshal(e)
return buf
}
func (e Error) Error() string {
return e.Message
}
func (e Error) HTTPCode() int {
var codes = map[uint8]int{
BadRequest: http.StatusBadRequest,
NotAllowed: http.StatusMethodNotAllowed,
Unsupported: http.StatusUnsupportedMediaType,
InternalError: http.StatusInternalServerError,
Unauthorized: http.StatusUnauthorized,
NotFound: http.StatusNotFound,
NotImplemented: http.StatusNotImplemented,
Forbidden: http.StatusForbidden,
NotAcceptable: http.StatusNotAcceptable,
}
if v, ok := codes[e.Code]; ok {
return v
}
return http.StatusServiceUnavailable
}
func NewError(err string, code uint8) Error {
err = strings.Replace(err, "\n", "", -1)
return Error{err, code}
}
func sendErrorResponse(w http.ResponseWriter, httpStatusCode int, imaginaryErrorCode uint8, err error) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(httpStatusCode)
_, _ = w.Write([]byte(fmt.Sprintf("{\"error\":\"%s\", \"code\": %d}", err.Error(), imaginaryErrorCode)))
}
func replyWithPlaceholder(req *http.Request, w http.ResponseWriter, errCaller Error, o ServerOptions) error {
var err error
bimgOptions := bimg.Options{
Force: true,
Crop: true,
Enlarge: true,
Type: ImageType(req.URL.Query().Get("type")),
}
bimgOptions.Width, err = parseInt(req.URL.Query().Get("width"))
if err != nil {
sendErrorResponse(w, http.StatusBadRequest, BadRequest, err)
return err
}
bimgOptions.Height, err = parseInt(req.URL.Query().Get("height"))
if err != nil {
sendErrorResponse(w, http.StatusBadRequest, BadRequest, err)
return err
}
// Resize placeholder to expected output
buf, err := bimg.Resize(o.PlaceholderImage, bimgOptions)
if err != nil {
sendErrorResponse(w, http.StatusBadRequest, BadRequest, err)
return err
}
// Use final response body image
image := buf
// Placeholder image response
w.Header().Set("Content-Type", GetImageMimeType(bimg.DetermineImageType(image)))
w.Header().Set("Error", string(errCaller.JSON()))
w.WriteHeader(errCaller.HTTPCode())
_, _ = w.Write(image)
return errCaller
}
func ErrorReply(req *http.Request, w http.ResponseWriter, err Error, o ServerOptions) {
// Reply with placeholder if required
if o.EnablePlaceholder || o.Placeholder != "" {
_ = replyWithPlaceholder(req, w, err, o)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(err.HTTPCode())
_, _ = w.Write(err.JSON())
}