-
Notifications
You must be signed in to change notification settings - Fork 5
/
errors.go
127 lines (102 loc) · 2.88 KB
/
errors.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
package don
import (
"bytes"
"context"
"encoding"
"encoding/xml"
"errors"
"strconv"
"github.com/abemedia/go-don/internal/byteconv"
"github.com/goccy/go-json"
"github.com/valyala/fasthttp"
"gopkg.in/yaml.v3"
)
func E(err error) fasthttp.RequestHandler {
h := H(func(context.Context, any) (any, error) { return nil, err })
return func(ctx *fasthttp.RequestCtx) { h(ctx, nil) }
}
type HTTPError struct {
err error
code int
}
func Error(err error, code int) *HTTPError {
return &HTTPError{err, code}
}
func (e *HTTPError) Error() string {
return e.err.Error()
}
func (e *HTTPError) Is(err error) bool {
return errors.Is(e.err, err) || errors.Is(StatusError(e.code), err)
}
func (e *HTTPError) Unwrap() error {
return e.err
}
func (e *HTTPError) StatusCode() int {
if e.code != 0 {
return e.code
}
var sc StatusCoder
if errors.As(e.err, &sc) {
return sc.StatusCode()
}
return fasthttp.StatusInternalServerError
}
func (e *HTTPError) MarshalText() ([]byte, error) {
var m encoding.TextMarshaler
if errors.As(e.err, &m) {
return m.MarshalText()
}
return byteconv.Atob(e.Error()), nil
}
func (e *HTTPError) MarshalJSON() ([]byte, error) {
var m json.Marshaler
if errors.As(e.err, &m) {
return m.MarshalJSON()
}
var buf bytes.Buffer
buf.WriteString(`{"message":`)
buf.WriteString(strconv.Quote(e.Error()))
buf.WriteRune('}')
return buf.Bytes(), nil
}
func (e *HTTPError) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {
var m xml.Marshaler
if errors.As(e.err, &m) {
return m.MarshalXML(enc, start)
}
start = xml.StartElement{Name: xml.Name{Local: "message"}}
return enc.EncodeElement(e.Error(), start)
}
func (e *HTTPError) MarshalYAML() (any, error) {
var m yaml.Marshaler
if errors.As(e.err, &m) {
return m.MarshalYAML()
}
return map[string]string{"message": e.Error()}, nil
}
var (
_ error = (*HTTPError)(nil)
_ encoding.TextMarshaler = (*HTTPError)(nil)
_ json.Marshaler = (*HTTPError)(nil)
_ xml.Marshaler = (*HTTPError)(nil)
_ yaml.Marshaler = (*HTTPError)(nil)
)
// StatusError creates an error from an HTTP status code.
type StatusError int
const (
ErrBadRequest = StatusError(fasthttp.StatusBadRequest)
ErrUnauthorized = StatusError(fasthttp.StatusUnauthorized)
ErrForbidden = StatusError(fasthttp.StatusForbidden)
ErrNotFound = StatusError(fasthttp.StatusNotFound)
ErrMethodNotAllowed = StatusError(fasthttp.StatusMethodNotAllowed)
ErrNotAcceptable = StatusError(fasthttp.StatusNotAcceptable)
ErrConflict = StatusError(fasthttp.StatusConflict)
ErrUnsupportedMediaType = StatusError(fasthttp.StatusUnsupportedMediaType)
ErrInternalServerError = StatusError(fasthttp.StatusInternalServerError)
)
func (e StatusError) Error() string {
return fasthttp.StatusMessage(int(e))
}
func (e StatusError) StatusCode() int {
return int(e)
}