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.
 
 
 
 

97 regels
1.9 KiB

  1. package gerrors
  2. import (
  3. "context"
  4. "egg-im/pkg/logger"
  5. "egg-im/pkg/util"
  6. "fmt"
  7. "go.uber.org/zap"
  8. "google.golang.org/grpc"
  9. "runtime"
  10. "strings"
  11. "github.com/golang/protobuf/ptypes/any"
  12. spb "google.golang.org/genproto/googleapis/rpc/status"
  13. "google.golang.org/grpc/codes"
  14. "google.golang.org/grpc/status"
  15. )
  16. const name = "im"
  17. const TypeUrlStack = "type_url_stack"
  18. func WrapError(err error) error {
  19. if err == nil {
  20. return nil
  21. }
  22. s := &spb.Status{
  23. Code: int32(codes.Unknown),
  24. Message: err.Error(),
  25. Details: []*any.Any{
  26. {
  27. TypeUrl: TypeUrlStack,
  28. Value: util.Str2bytes(stack()),
  29. },
  30. },
  31. }
  32. return status.FromProto(s).Err()
  33. }
  34. func WrapRPCError(err error) error {
  35. if err == nil {
  36. return nil
  37. }
  38. e, _ := status.FromError(err)
  39. s := &spb.Status{
  40. Code: int32(e.Code()),
  41. Message: e.Message(),
  42. Details: []*any.Any{
  43. {
  44. TypeUrl: TypeUrlStack,
  45. Value: util.Str2bytes(GetErrorStack(e) + " --grpc-- \n" + stack()),
  46. },
  47. },
  48. }
  49. return status.FromProto(s).Err()
  50. }
  51. func GetErrorStack(s *status.Status) string {
  52. pbs := s.Proto()
  53. for i := range pbs.Details {
  54. if pbs.Details[i].TypeUrl == TypeUrlStack {
  55. return util.Bytes2str(pbs.Details[i].Value)
  56. }
  57. }
  58. return ""
  59. }
  60. // Stack 获取堆栈信息
  61. func stack() string {
  62. var pc = make([]uintptr, 20)
  63. n := runtime.Callers(3, pc)
  64. var build strings.Builder
  65. for i := 0; i < n; i++ {
  66. f := runtime.FuncForPC(pc[i] - 1)
  67. file, line := f.FileLine(pc[i] - 1)
  68. n := strings.Index(file, name)
  69. if n != -1 {
  70. s := fmt.Sprintf(" %s:%d \n", file[n:], line)
  71. build.WriteString(s)
  72. }
  73. }
  74. return build.String()
  75. }
  76. func LogPanic(serverName string, ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, err *error) {
  77. p := recover()
  78. if p != nil {
  79. logger.Logger.Error(serverName+" panic", zap.Any("info", info), zap.Any("ctx", ctx), zap.Any("req", req),
  80. zap.Any("panic", p), zap.String("stack", util.GetStackInfo()))
  81. *err = ErrUnknown
  82. }
  83. }