Skip to content

Commit 3f976fc

Browse files
authored
feat: improve error handling (#85)
1 parent 5bd82f6 commit 3f976fc

File tree

3 files changed

+26
-57
lines changed

3 files changed

+26
-57
lines changed

encoding/text/encode.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ func encode(ctx *fasthttp.RequestCtx, v any) error {
4949
b = strconv.AppendFloat(ctx.Response.Body(), v, 'f', -1, 64)
5050
case bool:
5151
b = strconv.AppendBool(ctx.Response.Body(), v)
52-
case error:
53-
b = byteconv.Atob(v.Error())
5452
case encoding.TextMarshaler:
5553
b, err = v.MarshalText()
54+
case error:
55+
b = byteconv.Atob(v.Error())
5656
case fmt.Stringer:
5757
b = append(ctx.Response.Body(), v.String()...)
5858
default:

errors.go

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ func (e *HTTPError) Error() string {
3434
}
3535

3636
func (e *HTTPError) StatusCode() int {
37+
if e.code != 0 {
38+
return e.code
39+
}
40+
3741
var sc StatusCoder
3842
if errors.As(e.err, &sc) {
3943
return sc.StatusCode()
4044
}
4145

42-
if e.code == 0 {
43-
return http.StatusInternalServerError
44-
}
45-
46-
return e.code
46+
return http.StatusInternalServerError
4747
}
4848

4949
func (e *HTTPError) MarshalText() ([]byte, error) {
@@ -117,34 +117,3 @@ func (e StatusError) Error() string {
117117
func (e StatusError) StatusCode() int {
118118
return int(e)
119119
}
120-
121-
func (e StatusError) MarshalText() ([]byte, error) {
122-
return byteconv.Atob(e.Error()), nil
123-
}
124-
125-
func (e StatusError) MarshalJSON() ([]byte, error) {
126-
var buf bytes.Buffer
127-
128-
buf.WriteString(`{"message":`)
129-
buf.WriteString(strconv.Quote(e.Error()))
130-
buf.WriteRune('}')
131-
132-
return buf.Bytes(), nil
133-
}
134-
135-
func (e StatusError) MarshalXML(enc *xml.Encoder, _ xml.StartElement) error {
136-
start := xml.StartElement{Name: xml.Name{Local: "message"}}
137-
return enc.EncodeElement(e.Error(), start)
138-
}
139-
140-
func (e StatusError) MarshalYAML() (any, error) {
141-
return map[string]string{"message": e.Error()}, nil
142-
}
143-
144-
var (
145-
_ error = (*StatusError)(nil)
146-
_ encoding.TextMarshaler = (*StatusError)(nil)
147-
_ json.Marshaler = (*StatusError)(nil)
148-
_ xml.Marshaler = (*StatusError)(nil)
149-
_ yaml.Marshaler = (*StatusError)(nil)
150-
)

handler.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,16 @@ func H[T, O any](handle Handle[T, O]) httprouter.Handle { //nolint:gocognit,cycl
5555
return
5656
}
5757

58-
req := new(T)
59-
6058
var (
59+
req = new(T)
6160
res any
62-
e *HTTPError
6361
)
6462

6563
// Decode the header.
6664
if decodeHeader != nil {
6765
err = decodeHeader.Decode(&ctx.Request.Header, req)
6866
if err != nil {
69-
e = Error(err, http.StatusBadRequest)
67+
res = Error(err, http.StatusBadRequest)
7068
goto Encode
7169
}
7270
}
@@ -76,7 +74,7 @@ func H[T, O any](handle Handle[T, O]) httprouter.Handle { //nolint:gocognit,cycl
7674
if q := ctx.URI().QueryArgs(); q.Len() > 0 {
7775
err := decodeQuery.Decode(q, req)
7876
if err != nil {
79-
e = Error(err, http.StatusBadRequest)
77+
res = Error(err, http.StatusBadRequest)
8078
goto Encode
8179
}
8280
}
@@ -86,7 +84,7 @@ func H[T, O any](handle Handle[T, O]) httprouter.Handle { //nolint:gocognit,cycl
8684
if decodePath != nil && len(p) != 0 {
8785
err := decodePath.Decode(p, req)
8886
if err != nil {
89-
e = Error(err, http.StatusBadRequest)
87+
res = Error(ErrNotFound, 0)
9088
goto Encode
9189
}
9290
}
@@ -95,28 +93,24 @@ func H[T, O any](handle Handle[T, O]) httprouter.Handle { //nolint:gocognit,cycl
9593
if ctx.Request.Header.ContentLength() > 0 {
9694
dec, err := getDecoder(getEncoding(ctx.Request.Header.ContentType()))
9795
if err != nil {
98-
res = err
96+
res = Error(err, 0)
9997
goto Encode
10098
}
10199

102100
if err := dec(ctx, req); err != nil {
103-
e = Error(err, http.StatusBadRequest)
101+
res = Error(err, getStatusCode(err, http.StatusBadRequest))
104102
goto Encode
105103
}
106104
}
107105

108106
res, err = handle(ctx, *req)
109107
if err != nil {
110-
e = Error(err, 0)
108+
res = Error(err, 0)
111109
}
112110

113111
Encode:
114112
ctx.SetContentType(contentType + "; charset=utf-8")
115113

116-
if e != nil {
117-
res = e
118-
}
119-
120114
if h, ok := res.(Headerer); ok {
121115
for k, v := range h.Header() {
122116
ctx.Response.Header.Set(k, v[0])
@@ -139,13 +133,12 @@ func H[T, O any](handle Handle[T, O]) httprouter.Handle { //nolint:gocognit,cycl
139133
}
140134

141135
func handleError(ctx *fasthttp.RequestCtx, err error) {
142-
if statusCoder, ok := err.(StatusCoder); ok { //nolint:errorlint
143-
if sc := statusCoder.StatusCode(); sc < http.StatusInternalServerError {
144-
ctx.Error(err.Error()+"\n", sc)
145-
return
146-
}
136+
code := getStatusCode(err, http.StatusInternalServerError)
137+
if code < http.StatusInternalServerError {
138+
ctx.Error(err.Error()+"\n", code)
139+
return
147140
}
148-
ctx.Error(fasthttp.StatusMessage(http.StatusInternalServerError)+"\n", http.StatusInternalServerError)
141+
ctx.Error(fasthttp.StatusMessage(code)+"\n", code)
149142
ctx.Logger().Printf("%v", err)
150143
}
151144

@@ -158,6 +151,13 @@ func getEncoding(b []byte) string {
158151
return byteconv.Btoa(bytes.TrimSpace(b))
159152
}
160153

154+
func getStatusCode(i any, fallback int) int {
155+
if sc, ok := i.(StatusCoder); ok {
156+
return sc.StatusCode()
157+
}
158+
return fallback
159+
}
160+
161161
const (
162162
headerTag = "header"
163163
pathTag = "path"

0 commit comments

Comments
 (0)