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
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"codeberg.org/pronounscc/pronouns.cc/backend/log"
|
|
||||||
"codeberg.org/pronounscc/pronouns.cc/backend/server"
|
"codeberg.org/pronounscc/pronouns.cc/backend/server"
|
||||||
"github.com/aarondl/opt/omit"
|
"github.com/aarondl/opt/omit"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
|
@ -68,22 +65,11 @@ func (s *Server) UserAction(w http.ResponseWriter, r *http.Request) (err error)
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
claims, _ := server.ClaimsFromContext(ctx)
|
claims, _ := server.ClaimsFromContext(ctx)
|
||||||
|
|
||||||
var req UserActionRequest
|
req, err := server.Decode[UserActionRequest](r)
|
||||||
err = json.NewDecoder(r.Body).Decode(&req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: figure out why this isn't working
|
return err
|
||||||
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, "")
|
|
||||||
}
|
}
|
||||||
|
// validate input
|
||||||
if errs := req.Validate(); len(errs) != 0 {
|
if errs := req.Validate(); len(errs) != 0 {
|
||||||
return server.NewV2Error(server.ErrBadRequest, "", errs...)
|
return server.NewV2Error(server.ErrBadRequest, "", errs...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
json2 "github.com/aarondl/json"
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -58,6 +62,9 @@ type ModelParseError struct {
|
||||||
ExpectedValues []any `json:"expected_values,omitempty"`
|
ExpectedValues []any `json:"expected_values,omitempty"`
|
||||||
ActualValue any `json:"actual_value,omitempty"`
|
ActualValue any `json:"actual_value,omitempty"`
|
||||||
|
|
||||||
|
ExpectedType string `json:"expected_type,omitempty"`
|
||||||
|
ActualType string `json:"actual_type,omitempty"`
|
||||||
|
|
||||||
Key string `json:"-"`
|
Key string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,3 +89,48 @@ func NewModelParseErrorWithValues(key, message string, expectedValues []any, act
|
||||||
ActualValue: actualValue,
|
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