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
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())
|
||
|
//}
|
||
|
//
|
||
|
}
|