forked from mirrors/pronouns.cc
improve parse errors, they now return type errors, no field name though because that's broken for some reason
This commit is contained in:
parent
c8066be0a6
commit
9726827706
2 changed files with 55 additions and 17 deletions
|
@ -1,11 +1,8 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"codeberg.org/pronounscc/pronouns.cc/backend/log"
|
||||
"codeberg.org/pronounscc/pronouns.cc/backend/server"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/go-chi/render"
|
||||
|
@ -68,22 +65,11 @@ func (s *Server) UserAction(w http.ResponseWriter, r *http.Request) (err error)
|
|||
ctx := r.Context()
|
||||
claims, _ := server.ClaimsFromContext(ctx)
|
||||
|
||||
var req UserActionRequest
|
||||
err = json.NewDecoder(r.Body).Decode(&req)
|
||||
req, err := server.Decode[UserActionRequest](r)
|
||||
if err != nil {
|
||||
// TODO: figure out why this isn't working
|
||||
log.Debug(reflect.TypeOf(err).String())
|
||||
log.Debugf("%#v", err)
|
||||
log.Debugf("%T", err)
|
||||
if pe, ok := err.(*json.UnmarshalTypeError); ok {
|
||||
log.Debugf("value = %q, field = %q\n", pe.Value, pe.Field)
|
||||
} else {
|
||||
log.Debugf("type assertion for %T to *json.UnmarshalTypeError failed", err)
|
||||
}
|
||||
|
||||
return server.NewV2Error(server.ErrBadRequest, "")
|
||||
return err
|
||||
}
|
||||
|
||||
// validate input
|
||||
if errs := req.Validate(); len(errs) != 0 {
|
||||
return server.NewV2Error(server.ErrBadRequest, "", errs...)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
json2 "github.com/aarondl/json"
|
||||
"github.com/getsentry/sentry-go"
|
||||
)
|
||||
|
||||
|
@ -58,6 +62,9 @@ type ModelParseError struct {
|
|||
ExpectedValues []any `json:"expected_values,omitempty"`
|
||||
ActualValue any `json:"actual_value,omitempty"`
|
||||
|
||||
ExpectedType string `json:"expected_type,omitempty"`
|
||||
ActualType string `json:"actual_type,omitempty"`
|
||||
|
||||
Key string `json:"-"`
|
||||
}
|
||||
|
||||
|
@ -82,3 +89,48 @@ func NewModelParseErrorWithValues(key, message string, expectedValues []any, act
|
|||
ActualValue: actualValue,
|
||||
}
|
||||
}
|
||||
|
||||
func ParseJSONError(err error) *ModelParseError {
|
||||
switch pe := err.(type) {
|
||||
case *json.UnmarshalTypeError:
|
||||
key := pe.Field
|
||||
if key == "" {
|
||||
key = "parse"
|
||||
}
|
||||
|
||||
return &ModelParseError{
|
||||
Key: key,
|
||||
ExpectedType: pe.Type.String(),
|
||||
ActualType: pe.Value,
|
||||
}
|
||||
case *json2.UnmarshalTypeError:
|
||||
key := pe.Field
|
||||
if key == "" {
|
||||
key = "parse"
|
||||
}
|
||||
|
||||
return &ModelParseError{
|
||||
Key: key,
|
||||
ExpectedType: pe.Type.String(),
|
||||
ActualType: pe.Value,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Decode[T any](r *http.Request) (T, error) {
|
||||
var t T
|
||||
|
||||
b, _ := io.ReadAll(r.Body)
|
||||
err := json.Unmarshal(b, &t)
|
||||
// err := render.Decode(r, &t)
|
||||
if err != nil {
|
||||
pe := ParseJSONError(err)
|
||||
if pe != nil {
|
||||
return t, NewV2Error(ErrBadRequest, "", *pe)
|
||||
}
|
||||
return t, NewV2Error(ErrBadRequest, "")
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue