2019-06-03 20:44:43 +03:00
|
|
|
package grpc
|
|
|
|
|
|
|
|
import (
|
2020-09-20 16:08:45 +03:00
|
|
|
"context"
|
|
|
|
"io"
|
2019-06-03 20:44:43 +03:00
|
|
|
"net/http"
|
2020-09-20 16:08:45 +03:00
|
|
|
"os"
|
2019-06-03 20:44:43 +03:00
|
|
|
|
2020-09-20 16:08:45 +03:00
|
|
|
pb "github.com/unistack-org/micro-server-grpc/errors"
|
|
|
|
"github.com/unistack-org/micro/v3/errors"
|
2019-06-03 20:44:43 +03:00
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
)
|
|
|
|
|
2020-09-20 16:08:45 +03:00
|
|
|
var (
|
|
|
|
errMapping = map[int32]codes.Code{
|
|
|
|
http.StatusOK: codes.OK,
|
|
|
|
http.StatusBadRequest: codes.InvalidArgument,
|
|
|
|
http.StatusRequestTimeout: codes.DeadlineExceeded,
|
|
|
|
http.StatusNotFound: codes.NotFound,
|
|
|
|
http.StatusConflict: codes.AlreadyExists,
|
|
|
|
http.StatusForbidden: codes.PermissionDenied,
|
|
|
|
http.StatusUnauthorized: codes.Unauthenticated,
|
|
|
|
http.StatusPreconditionFailed: codes.FailedPrecondition,
|
|
|
|
http.StatusNotImplemented: codes.Unimplemented,
|
|
|
|
http.StatusInternalServerError: codes.Internal,
|
|
|
|
http.StatusServiceUnavailable: codes.Unavailable,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// convertCode converts a standard Go error into its canonical code. Note that
|
|
|
|
// this is only used to translate the error returned by the server applications.
|
|
|
|
func convertCode(err error) codes.Code {
|
|
|
|
switch err {
|
|
|
|
case nil:
|
|
|
|
return codes.OK
|
|
|
|
case io.EOF:
|
|
|
|
return codes.OutOfRange
|
|
|
|
case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
|
|
|
|
return codes.FailedPrecondition
|
|
|
|
case os.ErrInvalid:
|
|
|
|
return codes.InvalidArgument
|
|
|
|
case context.Canceled:
|
|
|
|
return codes.Canceled
|
|
|
|
case context.DeadlineExceeded:
|
|
|
|
return codes.DeadlineExceeded
|
|
|
|
}
|
|
|
|
switch {
|
|
|
|
case os.IsExist(err):
|
|
|
|
return codes.AlreadyExists
|
|
|
|
case os.IsNotExist(err):
|
|
|
|
return codes.NotFound
|
|
|
|
case os.IsPermission(err):
|
|
|
|
return codes.PermissionDenied
|
|
|
|
}
|
|
|
|
return codes.Unknown
|
2020-08-17 11:10:42 +03:00
|
|
|
}
|
|
|
|
|
2020-09-20 16:08:45 +03:00
|
|
|
func microError(err error) codes.Code {
|
2020-08-17 11:10:42 +03:00
|
|
|
if err == nil {
|
2019-06-03 20:44:43 +03:00
|
|
|
return codes.OK
|
|
|
|
}
|
|
|
|
|
2020-09-20 16:08:45 +03:00
|
|
|
var ec int32
|
|
|
|
switch verr := err.(type) {
|
|
|
|
case *errors.Error:
|
|
|
|
ec = verr.Code
|
|
|
|
case *pb.Error:
|
|
|
|
ec = verr.Code
|
|
|
|
}
|
|
|
|
|
|
|
|
if code, ok := errMapping[ec]; ok {
|
2020-08-17 11:10:42 +03:00
|
|
|
return code
|
2019-06-03 20:44:43 +03:00
|
|
|
}
|
2020-09-20 16:08:45 +03:00
|
|
|
|
2019-06-03 20:44:43 +03:00
|
|
|
return codes.Unknown
|
|
|
|
}
|
2020-09-20 16:08:45 +03:00
|
|
|
|
|
|
|
func pbError(err error) *pb.Error {
|
|
|
|
switch verr := err.(type) {
|
|
|
|
case nil:
|
|
|
|
return nil
|
|
|
|
case *errors.Error:
|
|
|
|
return &pb.Error{Id: verr.Id, Code: verr.Code, Detail: verr.Detail, Status: verr.Status}
|
|
|
|
case *pb.Error:
|
|
|
|
return verr
|
|
|
|
default:
|
|
|
|
return &pb.Error{Code: 500, Detail: err.Error()}
|
|
|
|
}
|
|
|
|
}
|