Skip to content

Commit 731c9e4

Browse files
committed
refactor: improved error responses from JSON decoders and encoders
1 parent 35c6e6c commit 731c9e4

File tree

9 files changed

+114
-42
lines changed

9 files changed

+114
-42
lines changed

http/handler/common.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
package handler
22

33
import (
4+
"errors"
45
gonethttp "github.com/ralvarezdev/go-net/http"
6+
gonethttpjson "github.com/ralvarezdev/go-net/http/json"
7+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
58
"net/http"
69
)
710

811
// SendInternalServerError sends an internal server error response
9-
func SendInternalServerError(w http.ResponseWriter) {
10-
http.Error(
11-
w,
12-
gonethttp.InternalServerError,
13-
http.StatusInternalServerError,
14-
)
12+
func SendInternalServerError(
13+
w http.ResponseWriter,
14+
encoder gonethttpjson.Encoder,
15+
) {
16+
if encoder != nil {
17+
_ = encoder.Encode(
18+
w,
19+
gonethttpresponse.NewJSONErrorResponse(errors.New(gonethttp.InternalServerError)),
20+
http.StatusInternalServerError,
21+
)
22+
} else {
23+
http.Error(
24+
w,
25+
gonethttp.InternalServerError,
26+
http.StatusInternalServerError,
27+
)
28+
}
1529
}

http/handler/handler.go

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package handler
33
import (
44
goflagsmode "github.com/ralvarezdev/go-flags/mode"
55
gonethttpjson "github.com/ralvarezdev/go-net/http/json"
6+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
67
"net/http"
78
)
89

@@ -14,11 +15,14 @@ type (
1415
r *http.Request,
1516
data interface{},
1617
) (err error)
17-
HandleResponse(w http.ResponseWriter, response *Response)
18+
HandleResponse(
19+
w http.ResponseWriter,
20+
response *gonethttpresponse.Response,
21+
)
1822
HandleErrorProneResponse(
1923
w http.ResponseWriter,
20-
successResponse *Response,
21-
errorResponse *Response,
24+
successResponse *gonethttpresponse.Response,
25+
errorResponse *gonethttpresponse.Response,
2226
)
2327
}
2428

@@ -66,22 +70,34 @@ func (d *DefaultHandler) HandleRequest(
6670
// HandleResponse handles the response
6771
func (d *DefaultHandler) HandleResponse(
6872
w http.ResponseWriter,
69-
response *Response,
73+
response *gonethttpresponse.Response,
7074
) {
7175
if response == nil {
7276
SendInternalServerError(w)
7377
return
7478
}
7579

76-
if response.Code != nil {
77-
if response.DebugData != nil && d.mode != nil && d.mode.IsDebug() {
78-
_ = d.jsonEncoder.Encode(w, response.DebugData, *response.Code)
80+
if gonethttpresponse.Code != nil {
81+
if gonethttpresponse.DebugData != nil && d.mode != nil && d.mode.IsDebug() {
82+
_ = d.jsonEncoder.Encode(
83+
w,
84+
gonethttpresponse.DebugData,
85+
*gonethttpresponse.Code,
86+
)
7987
return
8088
}
81-
_ = d.jsonEncoder.Encode(w, response.Data, *response.Code)
89+
_ = d.jsonEncoder.Encode(
90+
w,
91+
gonethttpresponse.Data,
92+
*gonethttpresponse.Code,
93+
)
8294
} else {
83-
if response.DebugData != nil && d.mode != nil && d.mode.IsDebug() {
84-
_ = d.jsonEncoder.Encode(w, response.DebugData, *response.Code)
95+
if gonethttpresponse.DebugData != nil && d.mode != nil && d.mode.IsDebug() {
96+
_ = d.jsonEncoder.Encode(
97+
w,
98+
gonethttpresponse.DebugData,
99+
*gonethttpresponse.Code,
100+
)
85101
return
86102
}
87103
SendInternalServerError(w)
@@ -91,8 +107,8 @@ func (d *DefaultHandler) HandleResponse(
91107
// HandleErrorProneResponse handles the response that may contain an error
92108
func (d *DefaultHandler) HandleErrorProneResponse(
93109
w http.ResponseWriter,
94-
successResponse *Response,
95-
errorResponse *Response,
110+
successResponse *gonethttpresponse.Response,
111+
errorResponse *gonethttpresponse.Response,
96112
) {
97113
// Check if the error response is nil
98114
if errorResponse != nil {

http/json/decoder.go

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package json
33
import (
44
"encoding/json"
55
goflagsmode "github.com/ralvarezdev/go-flags/mode"
6+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
67
"io"
78
"net/http"
89
)
@@ -19,12 +20,16 @@ type (
1920

2021
// DefaultDecoder struct
2122
DefaultDecoder struct {
22-
mode *goflagsmode.Flag
23+
mode *goflagsmode.Flag
24+
encoder Encoder
2325
}
2426
)
2527

2628
// NewDefaultDecoder creates a new JSON decoder
27-
func NewDefaultDecoder(mode *goflagsmode.Flag) *DefaultDecoder {
29+
func NewDefaultDecoder(
30+
mode *goflagsmode.Flag,
31+
encoder Encoder,
32+
) *DefaultDecoder {
2833
return &DefaultDecoder{
2934
mode: mode,
3035
}
@@ -44,21 +49,37 @@ func (d *DefaultDecoder) Decode(
4449
// Get the body of the request
4550
body, err := io.ReadAll(r.Body)
4651
if err != nil {
47-
http.Error(
48-
w,
49-
err.Error(),
50-
http.StatusBadRequest,
51-
)
52+
if d.encoder != nil {
53+
_ = d.encoder.Encode(
54+
w,
55+
gonethttpresponse.NewJSONErrorResponse(err),
56+
http.StatusInternalServerError,
57+
)
58+
} else {
59+
http.Error(
60+
w,
61+
err.Error(),
62+
http.StatusBadRequest,
63+
)
64+
}
5265
return err
5366
}
5467

5568
// Decode JSON data
5669
if err = json.Unmarshal(body, data); err != nil {
57-
http.Error(
58-
w,
59-
err.Error(),
60-
http.StatusBadRequest,
61-
)
70+
if d.encoder != nil {
71+
_ = d.encoder.Encode(
72+
w,
73+
gonethttpresponse.NewJSONErrorResponse(err),
74+
http.StatusInternalServerError,
75+
)
76+
} else {
77+
http.Error(
78+
w,
79+
err.Error(),
80+
http.StatusBadRequest,
81+
)
82+
}
6283
}
6384
return err
6485
}

http/json/encoder.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package json
33
import (
44
"encoding/json"
55
"github.com/ralvarezdev/go-flags/mode"
6+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
67
"net/http"
78
)
89

@@ -41,7 +42,11 @@ func (d *DefaultEncoder) Encode(
4142
// Encode the data
4243
jsonData, err := json.Marshal(data)
4344
if err != nil {
44-
http.Error(w, err.Error(), http.StatusInternalServerError)
45+
_ = d.Encode(
46+
w,
47+
gonethttpresponse.NewJSONErrorResponse(err),
48+
http.StatusInternalServerError,
49+
)
4550
return err
4651
}
4752

http/json/stream_decoder.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package json
33
import (
44
"encoding/json"
55
goflagsmode "github.com/ralvarezdev/go-flags/mode"
6+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
67
"net/http"
78
)
89

@@ -18,7 +19,8 @@ type (
1819

1920
// DefaultStreamDecoder is the JSON decoder struct
2021
DefaultStreamDecoder struct {
21-
mode *goflagsmode.Flag
22+
mode *goflagsmode.Flag
23+
streamEncoder StreamEncoder
2224
}
2325
)
2426

@@ -42,11 +44,19 @@ func (d *DefaultStreamDecoder) Decode(
4244

4345
// Decode JSON data
4446
if err = json.NewDecoder(r.Body).Decode(data); err != nil {
45-
http.Error(
46-
w,
47-
err.Error(),
48-
http.StatusBadRequest,
49-
)
47+
if d.streamEncoder != nil {
48+
_ = d.streamEncoder.Encode(
49+
w,
50+
gonethttpresponse.NewJSONErrorResponse(err),
51+
http.StatusInternalServerError,
52+
)
53+
} else {
54+
http.Error(
55+
w,
56+
err.Error(),
57+
http.StatusBadRequest,
58+
)
59+
}
5060
}
5161
return err
5262
}

http/json/stream_encoder.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package json
33
import (
44
"encoding/json"
55
goflagsmode "github.com/ralvarezdev/go-flags/mode"
6+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
67
"net/http"
78
)
89

@@ -40,7 +41,11 @@ func (d *DefaultStreamEncoder) Encode(
4041
w.WriteHeader(code)
4142
w.Header().Set("Content-Type", "application/json")
4243
if err = json.NewEncoder(w).Encode(data); err != nil {
43-
http.Error(w, err.Error(), http.StatusInternalServerError)
44+
_ = d.Encode(
45+
w,
46+
gonethttpresponse.NewJSONErrorResponse(err),
47+
http.StatusInternalServerError,
48+
)
4449
return err
4550
}
4651
return nil

http/jwt/validator/handler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package validator
22

33
import (
4-
gonethttpresponse "github.com/ralvarezdev/go-net/http/handler"
54
gonethttpjson "github.com/ralvarezdev/go-net/http/json"
5+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
66
"net/http"
77
)
88

http/middleware/auth/middleware.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
gonethttp "github.com/ralvarezdev/go-net/http"
1010
gonethttphandler "github.com/ralvarezdev/go-net/http/handler"
1111
gonethttpjwtvalidator "github.com/ralvarezdev/go-net/http/jwt/validator"
12+
"github.com/ralvarezdev/go-net/http/response"
1213
"net/http"
1314
"strings"
1415
)
@@ -62,7 +63,7 @@ func (m *Middleware) Authenticate(
6263
if !ok {
6364
m.handler.HandleResponse(
6465
w,
65-
gonethttphandler.NewErrorResponseWithCode(
66+
response.NewErrorResponseWithCode(
6667
gonethttp.ErrInvalidAuthorizationHeader,
6768
http.StatusUnauthorized,
6869
),
@@ -77,7 +78,7 @@ func (m *Middleware) Authenticate(
7778
if len(parts) < 2 || parts[0] != gojwt.BearerPrefix {
7879
m.handler.HandleResponse(
7980
w,
80-
gonethttphandler.NewErrorResponseWithCode(
81+
response.NewErrorResponseWithCode(
8182
gonethttp.ErrInvalidAuthorizationHeader,
8283
http.StatusUnauthorized,
8384
),

http/handler/types.go renamed to http/response/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package handler
1+
package response
22

33
type (
44
// Response struct

0 commit comments

Comments
 (0)