Skip to content

Commit 812726a

Browse files
committed
feat: added bodyDecodeErrorHandler function
1 parent ff4f18d commit 812726a

File tree

7 files changed

+101
-118
lines changed

7 files changed

+101
-118
lines changed

http/json/body.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package json
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
8+
"net/http"
9+
)
10+
11+
// bodyDecodeErrorHandler handles the error on JSON body decoding
12+
func bodyDecodeErrorHandler(
13+
w http.ResponseWriter,
14+
err error,
15+
encoder Encoder,
16+
) error {
17+
// Check if the encoder is nil
18+
if encoder == nil {
19+
return ErrNilEncoder
20+
}
21+
22+
// Check is there is an UnmarshalTypeError
23+
var unmarshalTypeError *json.UnmarshalTypeError
24+
if errors.As(err, &unmarshalTypeError) {
25+
// Check which field failed
26+
fieldName := unmarshalTypeError.Field
27+
fieldTypeName := unmarshalTypeError.Type.Name()
28+
fieldValue := unmarshalTypeError.Value
29+
30+
// Check if the field name is empty
31+
if fieldName != "" {
32+
return encoder.Encode(
33+
w,
34+
gonethttpresponse.NewDebugFailResponse(
35+
gonethttpresponse.NewSingleFieldErrorsBodyData(
36+
fieldName,
37+
fmt.Errorf(
38+
ErrFieldInvalidValue,
39+
fieldTypeName,
40+
fieldValue,
41+
),
42+
),
43+
err,
44+
nil,
45+
http.StatusBadRequest,
46+
),
47+
)
48+
}
49+
}
50+
51+
return encoder.Encode(
52+
w,
53+
gonethttpresponse.NewDebugFailResponse(
54+
ErrUnmarshalBodyDataFailed,
55+
err,
56+
nil,
57+
http.StatusBadRequest,
58+
),
59+
)
60+
}

http/json/data.go

Lines changed: 0 additions & 71 deletions
This file was deleted.

http/json/decoder.go

Lines changed: 18 additions & 17 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+
gonethttperrors "github.com/ralvarezdev/go-net/http/errors"
67
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
78
"io"
89
"net/http"
@@ -14,7 +15,7 @@ type (
1415
Decode(
1516
w http.ResponseWriter,
1617
r *http.Request,
17-
data interface{},
18+
dest interface{},
1819
) (err error)
1920
}
2021

@@ -41,34 +42,28 @@ func NewDefaultDecoder(
4142
}, nil
4243
}
4344

44-
// Decode decodes the JSON data from the request
45+
// Decode decodes the JSON request body and stores it in the destination
4546
func (d *DefaultDecoder) Decode(
4647
w http.ResponseWriter,
4748
r *http.Request,
48-
data interface{},
49+
dest interface{},
4950
) (err error) {
50-
// Check the data type
51-
if err = checkJSONData(w, data, d.mode, d.encoder); err != nil {
52-
return err
53-
}
54-
55-
// Get the body of the request
56-
body, err := io.ReadAll(r.Body)
57-
if err != nil {
51+
// Check the decoder destination
52+
if dest == nil {
5853
_ = d.encoder.Encode(
59-
w,
60-
gonethttpresponse.NewErrorResponse(
54+
w, gonethttpresponse.NewDebugErrorResponse(
55+
gonethttperrors.InternalServerError,
6156
err,
6257
nil,
6358
nil,
64-
http.StatusBadRequest,
59+
http.StatusInternalServerError,
6560
),
6661
)
67-
return err
6862
}
6963

70-
// Decode JSON data
71-
if err = json.Unmarshal(body, data); err != nil {
64+
// Get the body of the request
65+
body, err := io.ReadAll(r.Body)
66+
if err != nil {
7267
_ = d.encoder.Encode(
7368
w,
7469
gonethttpresponse.NewErrorResponse(
@@ -78,6 +73,12 @@ func (d *DefaultDecoder) Decode(
7873
http.StatusBadRequest,
7974
),
8075
)
76+
return err
77+
}
78+
79+
// Decode JSON body into destination
80+
if err = json.Unmarshal(body, dest); err != nil {
81+
_ = bodyDecodeErrorHandler(w, err, d.encoder)
8182
}
8283
return err
8384
}

http/json/encoder.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func NewDefaultEncoder(mode *mode.Flag) *DefaultEncoder {
2828
return &DefaultEncoder{mode: mode}
2929
}
3030

31-
// Encode encodes the given data to JSON
31+
// Encode encodes the body into JSON and writes it to the response
3232
func (d *DefaultEncoder) Encode(
3333
w http.ResponseWriter,
3434
response *gonethttpresponse.Response,
@@ -37,12 +37,7 @@ func (d *DefaultEncoder) Encode(
3737
body := response.GetBody(d.mode)
3838
httpStatus := response.GetHTTPStatus()
3939

40-
// Check the data type
41-
if err = checkJSONData(w, body, d.mode, d); err != nil {
42-
return err
43-
}
44-
45-
// Encode the data
40+
// Encode the JSON body
4641
jsonBody, err := json.Marshal(body)
4742
if err != nil {
4843
return d.Encode(
@@ -52,7 +47,7 @@ func (d *DefaultEncoder) Encode(
5247
err,
5348
nil,
5449
nil,
55-
http.StatusBadRequest,
50+
http.StatusInternalServerError,
5651
),
5752
)
5853
}

http/json/errors.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
)
66

77
var (
8-
ErrNilJSONData = errors.New("json data is nil")
9-
ErrNilEncoder = errors.New("json encoder is nil")
10-
ErrNilDecoder = errors.New("json decoder is nil")
8+
ErrNilData = errors.New("json data is nil")
9+
ErrNilEncoder = errors.New("json encoder is nil")
10+
ErrNilDecoder = errors.New("json decoder is nil")
11+
ErrUnmarshalBodyDataFailed = errors.New("failed to unmarshal json body data")
12+
ErrFieldInvalidValue = "field has an invalid value %v, it must be %v"
1113
)

http/json/stream_decoder.go

Lines changed: 12 additions & 11 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+
gonethttperrors "github.com/ralvarezdev/go-net/http/errors"
67
gonethttpresponse "github.com/ralvarezdev/go-net/http/response"
78
"net/http"
89
)
@@ -31,28 +32,28 @@ func NewDefaultStreamDecoder(
3132
}, nil
3233
}
3334

34-
// Decode decodes the JSON data
35+
// Decode decodes the JSON request body and stores it in the destination
3536
func (d *DefaultStreamDecoder) Decode(
3637
w http.ResponseWriter,
3738
r *http.Request,
38-
data interface{},
39+
dest interface{},
3940
) (err error) {
40-
// Check the data type
41-
if err = checkJSONData(w, data, d.mode, d.encoder); err != nil {
42-
return err
43-
}
44-
45-
// Decode JSON data
46-
if err = json.NewDecoder(r.Body).Decode(data); err != nil {
41+
// Check the decoder destination
42+
if dest == nil {
4743
_ = d.encoder.Encode(
48-
w,
49-
gonethttpresponse.NewErrorResponse(
44+
w, gonethttpresponse.NewDebugErrorResponse(
45+
gonethttperrors.InternalServerError,
5046
err,
5147
nil,
5248
nil,
5349
http.StatusInternalServerError,
5450
),
5551
)
5652
}
53+
54+
// Decode JSON body into destination
55+
if err = json.NewDecoder(r.Body).Decode(dest); err != nil {
56+
_ = bodyDecodeErrorHandler(w, err, d.encoder)
57+
}
5758
return err
5859
}

http/json/stream_encoder.go

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,16 @@ func NewDefaultStreamEncoder(mode *goflagsmode.Flag) *DefaultStreamEncoder {
2222
}
2323
}
2424

25-
// Encode encodes the data into JSON
25+
// Encode encodes the body into JSON and writes it to the response
2626
func (d *DefaultStreamEncoder) Encode(
2727
w http.ResponseWriter,
2828
response *gonethttpresponse.Response,
2929
) (err error) {
30-
// Get the data from the response
30+
// Get the body and HTTP status from the response
3131
body := response.GetBody(d.mode)
3232
httpStatus := response.GetHTTPStatus()
3333

34-
// Check the data type
35-
if err = checkJSONData(w, body, d.mode, d); err != nil {
36-
return err
37-
}
38-
39-
// Encode JSON data and write it to the response
34+
// Encode the JSON body
4035
if err = json.NewEncoder(w).Encode(body); err != nil {
4136
_ = d.Encode(
4237
w,

0 commit comments

Comments
 (0)