From 66412031fdf4d6cc4c7137a3bd72f823ca97d178 Mon Sep 17 00:00:00 2001 From: Tony Chen Date: Tue, 25 May 2021 15:01:53 +0800 Subject: [PATCH] errors: refactor status code (#948) * refactor status code --- errors/errors.go | 43 +++++++++------------ errors/errors.pb.go | 61 ++++++++++++------------------ errors/errors.proto | 8 ++-- errors/errors_test.go | 12 ++---- errors/types.go | 46 ++++++++++------------ errors/types_test.go | 14 +++---- examples/helloworld/server/main.go | 2 +- middleware/recovery/recovery.go | 2 +- middleware/validate/validate.go | 2 +- transport/http/client.go | 7 ++-- transport/http/handle.go | 18 +++++---- 11 files changed, 94 insertions(+), 121 deletions(-) diff --git a/errors/errors.go b/errors/errors.go index a6e40486c..2d66bee41 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -11,22 +11,24 @@ import ( "google.golang.org/protobuf/proto" ) +// UnknownReason is unknown reason for error info. +const UnknownReason = "" + //go:generate protoc -I. --go_out=paths=source_relative:. errors.proto func (e *Error) Error() string { - return fmt.Sprintf("error: domain = %s reason = %s metadata = %v", e.Domain, e.Reason, e.Metadata) + return fmt.Sprintf("error: code = %d reason = %s message = %s metadata = %v", e.Code, e.Reason, e.Message, e.Metadata) } -// HTTPStatus return an HTTP error code. -func (e *Error) HTTPStatus() int { - return httputil.StatusFromGRPCCode(codes.Code(e.Code)) +// StatusCode return an HTTP error code. +func (e *Error) StatusCode() int { + return int(e.Code) } // GRPCStatus returns the Status represented by se. func (e *Error) GRPCStatus() *status.Status { - s, _ := status.New(codes.Code(e.Code), e.Message). + s, _ := status.New(httputil.GRPCCodeFromStatus(e.StatusCode()), e.Message). WithDetails(&errdetails.ErrorInfo{ - Domain: e.Domain, Reason: e.Reason, Metadata: e.Metadata, }) @@ -36,7 +38,7 @@ func (e *Error) GRPCStatus() *status.Status { // Is matches each error in the chain with the target value. func (e *Error) Is(err error) bool { if se := new(Error); errors.As(err, &se) { - return se.Domain == e.Domain && se.Reason == e.Reason + return se.Reason == e.Reason } return false } @@ -49,23 +51,22 @@ func (e *Error) WithMetadata(md map[string]string) *Error { } // New returns an error object for the code, message. -func New(code codes.Code, domain, reason, message string) *Error { +func New(code int, reason, message string) *Error { return &Error{ Code: int32(code), Message: message, - Domain: domain, Reason: reason, } } // Newf New(code fmt.Sprintf(format, a...)) -func Newf(code codes.Code, domain, reason, format string, a ...interface{}) *Error { - return New(code, domain, reason, fmt.Sprintf(format, a...)) +func Newf(code int, reason, format string, a ...interface{}) *Error { + return New(code, reason, fmt.Sprintf(format, a...)) } // Errorf returns an error object for the code, message and error info. -func Errorf(code codes.Code, domain, reason, format string, a ...interface{}) error { - return New(code, domain, reason, fmt.Sprintf(format, a...)) +func Errorf(code int, reason, format string, a ...interface{}) error { + return New(code, reason, fmt.Sprintf(format, a...)) } // Code returns the code for a particular error. @@ -80,22 +81,13 @@ func Code(err error) codes.Code { return codes.Unknown } -// Domain returns the domain for a particular error. -// It supports wrapped errors. -func Domain(err error) string { - if se := FromError(err); err != nil { - return se.Domain - } - return "" -} - // Reason returns the reason for a particular error. // It supports wrapped errors. func Reason(err error) string { if se := FromError(err); err != nil { return se.Reason } - return "" + return UnknownReason } // FromError try to convert an error to *Error. @@ -113,13 +105,12 @@ func FromError(err error) *Error { switch d := detail.(type) { case *errdetails.ErrorInfo: return New( - gs.Code(), - d.Domain, + httputil.StatusFromGRPCCode(gs.Code()), d.Reason, gs.Message(), ).WithMetadata(d.Metadata) } } } - return New(gs.Code(), "", "", err.Error()) + return New(httputil.StatusFromGRPCCode(gs.Code()), UnknownReason, err.Error()) } diff --git a/errors/errors.pb.go b/errors/errors.pb.go index 17dc0c195..05d77624b 100644 --- a/errors/errors.pb.go +++ b/errors/errors.pb.go @@ -25,12 +25,10 @@ type Error struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - // error details - Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` - Domain string `protobuf:"bytes,4,opt,name=domain,proto3" json:"domain,omitempty"` - Metadata map[string]string `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Error) Reset() { @@ -72,13 +70,6 @@ func (x *Error) GetCode() int32 { return 0 } -func (x *Error) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - func (x *Error) GetReason() string { if x != nil { return x.Reason @@ -86,9 +77,9 @@ func (x *Error) GetReason() string { return "" } -func (x *Error) GetDomain() string { +func (x *Error) GetMessage() string { if x != nil { - return x.Domain + return x.Message } return "" } @@ -104,28 +95,26 @@ var File_errors_proto protoreflect.FileDescriptor var file_errors_proto_rawDesc = []byte{ 0x0a, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, - 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0xe2, 0x01, + 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0xca, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x3e, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, - 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x42, 0x59, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, - 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, - 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x32, - 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x3b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa2, 0x02, - 0x0c, 0x4b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3e, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x22, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x2e, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, + 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x59, 0x0a, 0x18, 0x63, 0x6f, + 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x50, 0x01, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x6b, + 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x3b, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0xa2, 0x02, 0x0c, 0x4b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/errors/errors.proto b/errors/errors.proto index 2553932bb..6439c3f16 100644 --- a/errors/errors.proto +++ b/errors/errors.proto @@ -9,9 +9,7 @@ option objc_class_prefix = "KratosErrors"; message Error { int32 code = 1; - string message = 2; - // error details - string reason = 3; - string domain = 4; - map metadata = 5; + string reason = 2; + string message = 3; + map metadata = 4; }; diff --git a/errors/errors_test.go b/errors/errors_test.go index 5031f1903..b7e5fd1b0 100644 --- a/errors/errors_test.go +++ b/errors/errors_test.go @@ -3,17 +3,16 @@ package errors import ( "errors" "fmt" + "net/http" "testing" - - "google.golang.org/grpc/codes" ) func TestError(t *testing.T) { var ( base *Error ) - err := Newf(codes.InvalidArgument, "domain", "reason", "message") - err2 := Newf(codes.InvalidArgument, "domain", "reason", "message") + err := Newf(http.StatusBadRequest, "reason", "message") + err2 := Newf(http.StatusBadRequest, "reason", "message") err3 := err.WithMetadata(map[string]string{ "foo": "bar", }) @@ -36,9 +35,6 @@ func TestError(t *testing.T) { t.Errorf("should be matchs: %v", err) } - if domain := Domain(err); domain != err2.Domain { - t.Errorf("got %s want: %s", domain, err) - } if reason := Reason(err); reason != err3.Reason { t.Errorf("got %s want: %s", reason, err) } @@ -49,7 +45,7 @@ func TestError(t *testing.T) { gs := err.GRPCStatus() se := FromError(gs.Err()) - if se.Domain != err.Domain || se.Reason != se.Reason { + if se.Reason != se.Reason { t.Errorf("got %+v want %+v", se, err) } } diff --git a/errors/types.go b/errors/types.go index b96b8f899..d9b1dfb42 100644 --- a/errors/types.go +++ b/errors/types.go @@ -1,82 +1,78 @@ package errors -import ( - "google.golang.org/grpc/codes" -) - // BadRequest new BadRequest error that is mapped to a 400 response. -func BadRequest(domain, reason, message string) *Error { - return Newf(codes.InvalidArgument, domain, reason, message) +func BadRequest(reason, message string) *Error { + return Newf(400, reason, message) } // IsBadRequest determines if err is an error which indicates a BadRequest error. // It supports wrapped errors. func IsBadRequest(err error) bool { - return Code(err) == codes.InvalidArgument + return Code(err) == 400 } // Unauthorized new Unauthorized error that is mapped to a 401 response. -func Unauthorized(domain, reason, message string) *Error { - return Newf(codes.Unauthenticated, domain, reason, message) +func Unauthorized(reason, message string) *Error { + return Newf(401, reason, message) } // IsUnauthorized determines if err is an error which indicates a Unauthorized error. // It supports wrapped errors. func IsUnauthorized(err error) bool { - return Code(err) == codes.Unauthenticated + return Code(err) == 401 } // Forbidden new Forbidden error that is mapped to a 403 response. -func Forbidden(domain, reason, message string) *Error { - return Newf(codes.PermissionDenied, domain, reason, message) +func Forbidden(reason, message string) *Error { + return Newf(403, reason, message) } // IsForbidden determines if err is an error which indicates a Forbidden error. // It supports wrapped errors. func IsForbidden(err error) bool { - return Code(err) == codes.PermissionDenied + return Code(err) == 403 } // NotFound new NotFound error that is mapped to a 404 response. -func NotFound(domain, reason, message string) *Error { - return Newf(codes.NotFound, domain, reason, message) +func NotFound(reason, message string) *Error { + return Newf(404, reason, message) } // IsNotFound determines if err is an error which indicates an NotFound error. // It supports wrapped errors. func IsNotFound(err error) bool { - return Code(err) == codes.NotFound + return Code(err) == 404 } // Conflict new Conflict error that is mapped to a 409 response. -func Conflict(domain, reason, message string) *Error { - return Newf(codes.Aborted, domain, reason, message) +func Conflict(reason, message string) *Error { + return Newf(409, reason, message) } // IsConflict determines if err is an error which indicates a Conflict error. // It supports wrapped errors. func IsConflict(err error) bool { - return Code(err) == codes.Aborted + return Code(err) == 409 } // InternalServer new InternalServer error that is mapped to a 500 response. -func InternalServer(domain, reason, message string) *Error { - return Newf(codes.Internal, domain, reason, message) +func InternalServer(reason, message string) *Error { + return Newf(500, reason, message) } // IsInternalServer determines if err is an error which indicates an Internal error. // It supports wrapped errors. func IsInternalServer(err error) bool { - return Code(err) == codes.Internal + return Code(err) == 500 } // ServiceUnavailable new ServiceUnavailable error that is mapped to a HTTP 503 response. -func ServiceUnavailable(domain, reason, message string) *Error { - return Newf(codes.Unavailable, domain, reason, message) +func ServiceUnavailable(reason, message string) *Error { + return Newf(503, reason, message) } // IsServiceUnavailable determines if err is an error which indicates a Unavailable error. // It supports wrapped errors. func IsServiceUnavailable(err error) bool { - return Code(err) == codes.Unavailable + return Code(err) == 503 } diff --git a/errors/types_test.go b/errors/types_test.go index 35d83df16..94841f031 100644 --- a/errors/types_test.go +++ b/errors/types_test.go @@ -5,13 +5,13 @@ import "testing" func TestTypes(t *testing.T) { var ( input = []error{ - BadRequest("domain_400", "reason_400", "message_400"), - Unauthorized("domain_401", "reason_401", "message_401"), - Forbidden("domain_403", "reason_403", "message_403"), - NotFound("domain_404", "reason_404", "message_404"), - Conflict("domain_409", "reason_409", "message_409"), - InternalServer("domain_500", "reason_500", "message_500"), - ServiceUnavailable("domain_503", "reason_503", "message_503"), + BadRequest("reason_400", "message_400"), + Unauthorized("reason_401", "message_401"), + Forbidden("reason_403", "message_403"), + NotFound("reason_404", "message_404"), + Conflict("reason_409", "message_409"), + InternalServer("reason_500", "message_500"), + ServiceUnavailable("reason_503", "message_503"), } output = []func(error) bool{ IsBadRequest, diff --git a/examples/helloworld/server/main.go b/examples/helloworld/server/main.go index bd5fdca18..a196553d1 100644 --- a/examples/helloworld/server/main.go +++ b/examples/helloworld/server/main.go @@ -31,7 +31,7 @@ type server struct { // SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { if in.Name == "error" { - return nil, errors.BadRequest(Name, "custom_error", fmt.Sprintf("invalid argument %s", in.Name)) + return nil, errors.BadRequest("custom_error", fmt.Sprintf("invalid argument %s", in.Name)) } if in.Name == "panic" { panic("grpc panic") diff --git a/middleware/recovery/recovery.go b/middleware/recovery/recovery.go index f8a771297..ed9613e96 100644 --- a/middleware/recovery/recovery.go +++ b/middleware/recovery/recovery.go @@ -40,7 +40,7 @@ func Recovery(opts ...Option) middleware.Middleware { options := options{ logger: log.DefaultLogger, handler: func(ctx context.Context, req, err interface{}) error { - return errors.InternalServer("global", "recovery", fmt.Sprintf("panic triggered: %v", err)) + return errors.InternalServer("RECOVERY", fmt.Sprintf("panic triggered: %v", err)) }, } for _, o := range opts { diff --git a/middleware/validate/validate.go b/middleware/validate/validate.go index a872b486f..a6eee1f0d 100644 --- a/middleware/validate/validate.go +++ b/middleware/validate/validate.go @@ -17,7 +17,7 @@ func Validator() middleware.Middleware { return func(ctx context.Context, req interface{}) (reply interface{}, err error) { if v, ok := req.(validator); ok { if err := v.Validate(); err != nil { - return nil, errors.BadRequest("global", "validator", err.Error()) + return nil, errors.BadRequest("VALIDATOR", err.Error()) } } return handler(ctx, req) diff --git a/transport/http/client.go b/transport/http/client.go index dc348cdb5..80525690b 100644 --- a/transport/http/client.go +++ b/transport/http/client.go @@ -262,13 +262,14 @@ func defaultErrorDecoder(ctx context.Context, res *http.Response) error { return nil } defer res.Body.Close() - if data, err := ioutil.ReadAll(res.Body); err == nil { + data, err := ioutil.ReadAll(res.Body) + if err == nil { e := new(errors.Error) - if err := codecForResponse(res).Unmarshal(data, e); err == nil { + if err = codecForResponse(res).Unmarshal(data, e); err == nil { return e } } - return errors.Errorf(httputil.GRPCCodeFromStatus(res.StatusCode), "", "", "") + return errors.Errorf(res.StatusCode, errors.UnknownReason, err.Error()) } func codecForResponse(r *http.Response) encoding.Codec { diff --git a/transport/http/handle.go b/transport/http/handle.go index 5f64f7030..e843240f8 100644 --- a/transport/http/handle.go +++ b/transport/http/handle.go @@ -157,18 +157,18 @@ func defaultRequestDecoder(req *http.Request, v interface{}) error { if codec := encoding.GetCodec(subtype); codec != nil { data, err := ioutil.ReadAll(req.Body) if err != nil { - return errors.BadRequest("global", "codec", err.Error()) + return errors.BadRequest("CODEC", err.Error()) } if err := codec.Unmarshal(data, v); err != nil { - return errors.BadRequest("global", "codec", err.Error()) + return errors.BadRequest("CODEC", err.Error()) } } else { if err := binding.BindForm(req, v); err != nil { - return errors.BadRequest("global", "codec", err.Error()) + return errors.BadRequest("CODEC", err.Error()) } } if err := binding.BindVars(mux.Vars(req), v); err != nil { - return errors.BadRequest("global", "codec", err.Error()) + return errors.BadRequest("CODEC", err.Error()) } return nil } @@ -182,9 +182,9 @@ func defaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{ } w.Header().Set("Content-Type", httputil.ContentType(codec.Name())) if sc, ok := v.(interface { - HTTPStatus() int + StatusCode() int }); ok { - w.WriteHeader(sc.HTTPStatus()) + w.WriteHeader(sc.StatusCode()) } _, _ = w.Write(data) return nil @@ -200,9 +200,11 @@ func defaultErrorEncoder(w http.ResponseWriter, r *http.Request, se error) { } w.Header().Set("Content-Type", httputil.ContentType(codec.Name())) if sc, ok := se.(interface { - HTTPStatus() int + StatusCode() int }); ok { - w.WriteHeader(sc.HTTPStatus()) + w.WriteHeader(sc.StatusCode()) + } else { + w.WriteHeader(http.StatusInternalServerError) } w.Write(body) }