forked from TrueCloudLab/certificates
Improve read.ProtoJSON bad protobuf body error handling
This commit is contained in:
parent
647538e9e8
commit
6532c93303
1 changed files with 24 additions and 37 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/smallstep/certificates/api/render"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
)
|
||||
|
||||
|
@ -29,49 +30,35 @@ func ProtoJSON(r io.Reader, m proto.Message) error {
|
|||
if err != nil {
|
||||
return errs.BadRequestErr(err, "error reading request body")
|
||||
}
|
||||
if err := protojson.Unmarshal(data, m); err != nil {
|
||||
if errors.Is(err, proto.Error) {
|
||||
return newBadProtoJSONError(err)
|
||||
}
|
||||
|
||||
switch err := protojson.Unmarshal(data, m); {
|
||||
case errors.Is(err, proto.Error):
|
||||
return badProtoJSONError(err.Error())
|
||||
default:
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// BadProtoJSONError is an error type that is used when a proto
|
||||
// message cannot be unmarshaled. Usually this is caused by an error
|
||||
// in the request body.
|
||||
type BadProtoJSONError struct {
|
||||
err error
|
||||
Type string `json:"type"`
|
||||
Detail string `json:"detail"`
|
||||
Message string `json:"message"`
|
||||
// badProtoJSONError is an error type that is returned by ProtoJSON
|
||||
// when a proto message cannot be unmarshaled. Usually this is caused
|
||||
// by an error in the request body.
|
||||
type badProtoJSONError string
|
||||
|
||||
// Error implements error for badProtoJSONError
|
||||
func (e badProtoJSONError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
// newBadProtoJSONError returns a new instance of BadProtoJSONError
|
||||
// This error type is always caused by an error in the request body.
|
||||
func newBadProtoJSONError(err error) *BadProtoJSONError {
|
||||
return &BadProtoJSONError{
|
||||
err: err,
|
||||
// Render implements render.RenderableError for badProtoJSONError
|
||||
func (e badProtoJSONError) Render(w http.ResponseWriter) {
|
||||
v := struct {
|
||||
Type string `json:"type"`
|
||||
Detail string `json:"detail"`
|
||||
Message string `json:"message"`
|
||||
}{
|
||||
Type: "badRequest",
|
||||
Detail: "bad request",
|
||||
Message: err.Error(),
|
||||
Message: e.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
// Error implements the error interface
|
||||
func (e *BadProtoJSONError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
// Render implements render.RenderableError for BadProtoError
|
||||
func (e *BadProtoJSONError) Render(w http.ResponseWriter) {
|
||||
|
||||
errData, err := json.Marshal(e)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write(errData)
|
||||
render.JSONStatus(w, v, http.StatusBadRequest)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue