You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
1.5 KiB

2 years ago
package xerrors
import (
"errors"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
const (
// UnknownCode is unknown code for error info.
UnknownCode = 500
// UnknownReason is unknown reason for error info.
UnknownReason = ""
)
type Error struct {
Status int
Message string
Reason string
Metadata map[string]string
}
func (e *Error) WithMetadata(data map[string]string) *Error {
err := Clone(e)
err.Metadata = data
return err
}
func (s *Error) Error() string {
return s.Message
}
func New(code int, reason, message string) *Error {
return &Error{
Status: code,
Message: message,
Reason: reason,
Metadata: map[string]string{},
}
}
func (e *Error) GRPCStatus() *status.Status {
s, _ := status.New(codes.Code(e.Status), e.Message).
WithDetails(&errdetails.ErrorInfo{
Reason: e.Reason,
Metadata: e.Metadata,
})
return s
}
func Clone(err *Error) *Error {
if err == nil {
return nil
}
metadata := make(map[string]string, len(err.Metadata))
for k, v := range err.Metadata {
metadata[k] = v
}
return &Error{
Status: err.Status,
Reason: err.Reason,
Message: err.Message,
Metadata: metadata,
}
}
func Code(err error) int {
if err == nil {
return 200
}
return FromError(err).Status
}
func FromError(err error) *Error {
if err == nil {
return nil
}
if se := new(Error); errors.As(err, &se) {
return se
}
//gs, ok := status.FromError(err)
//if !ok {
return New(UnknownCode, UnknownReason, err.Error())
//}
//
}