59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package apperr
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
// Error 表示网关内部统一业务错误。
|
|
type Error struct {
|
|
Status int
|
|
Code string
|
|
Message string
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
return e.Message
|
|
}
|
|
|
|
// New 构造一个统一错误,便于 HTTP 层直接映射。
|
|
func New(status int, code string, message string) *Error {
|
|
return &Error{
|
|
Status: status,
|
|
Code: code,
|
|
Message: message,
|
|
}
|
|
}
|
|
|
|
// Resolve 将任意错误转换成统一 HTTP 状态码和错误码。
|
|
func Resolve(err error) (statusCode int, code string, message string) {
|
|
if err == nil {
|
|
return 200, "ok", "ok"
|
|
}
|
|
|
|
var appErr *Error
|
|
if errors.As(err, &appErr) {
|
|
return appErr.Status, appErr.Code, appErr.Message
|
|
}
|
|
|
|
grpcStatus, ok := status.FromError(err)
|
|
if !ok {
|
|
return 500, "internal_error", "internal server error"
|
|
}
|
|
|
|
switch grpcStatus.Code() {
|
|
case codes.InvalidArgument:
|
|
return 400, "bad_request", grpcStatus.Message()
|
|
case codes.Unauthenticated, codes.PermissionDenied:
|
|
return 401, "unauthorized", grpcStatus.Message()
|
|
case codes.NotFound:
|
|
return 404, "not_found", grpcStatus.Message()
|
|
case codes.DeadlineExceeded:
|
|
return 504, "upstream_timeout", "upstream request timeout"
|
|
default:
|
|
return 502, "upstream_error", grpcStatus.Message()
|
|
}
|
|
}
|