go.undefinedlabs.com/scopeagent@v0.4.2/instrumentation/grpc/errors.go (about) 1 package grpc 2 3 import ( 4 "github.com/opentracing/opentracing-go" 5 "github.com/opentracing/opentracing-go/ext" 6 "google.golang.org/grpc/codes" 7 "google.golang.org/grpc/status" 8 ) 9 10 // A Class is a set of types of outcomes (including errors) that will often 11 // be handled in the same way. 12 type Class string 13 14 const ( 15 Unknown Class = "0xx" 16 // Success represents outcomes that achieved the desired results. 17 Success Class = "2xx" 18 // ClientError represents errors that were the client's fault. 19 ClientError Class = "4xx" 20 // ServerError represents errors that were the server's fault. 21 ServerError Class = "5xx" 22 ) 23 24 var classStrings = map[Class]string{ 25 Unknown: "Unknown (0xx)", 26 Success: "Success (2xx)", 27 ClientError: "ClientError (4xx)", 28 ServerError: "ServerError (5xx)", 29 } 30 31 var codeStrings = map[codes.Code]string{ 32 codes.OK: "OK", 33 codes.Canceled: "Canceled", 34 codes.Unknown: "Unknown", 35 codes.InvalidArgument: "InvalidArgument", 36 codes.DeadlineExceeded: "DeadlineExceeded", 37 codes.NotFound: "NotFound", 38 codes.AlreadyExists: "AlreadyExists", 39 codes.PermissionDenied: "PermissionDenied", 40 codes.ResourceExhausted: "ResourceExhausted", 41 codes.FailedPrecondition: "FailedPrecondition", 42 codes.Aborted: "Aborted", 43 codes.OutOfRange: "OutOfRange", 44 codes.Unimplemented: "Unimplemented", 45 codes.Internal: "Internal", 46 codes.Unavailable: "Unavailable", 47 codes.DataLoss: "DataLoss", 48 codes.Unauthenticated: "Unauthenticated", 49 } 50 51 // ErrorClass returns the class of the given error 52 func ErrorClass(err error) Class { 53 if s, ok := status.FromError(err); ok { 54 switch s.Code() { 55 // Success or "success" 56 case codes.OK, codes.Canceled: 57 return Success 58 59 // Client errors 60 case codes.InvalidArgument, codes.NotFound, codes.AlreadyExists, 61 codes.PermissionDenied, codes.Unauthenticated, codes.FailedPrecondition, 62 codes.OutOfRange: 63 return ClientError 64 65 // Server errors 66 case codes.DeadlineExceeded, codes.ResourceExhausted, codes.Aborted, 67 codes.Unimplemented, codes.Internal, codes.Unavailable, codes.DataLoss: 68 return ServerError 69 70 // Not sure 71 case codes.Unknown: 72 fallthrough 73 default: 74 return Unknown 75 } 76 } 77 return Unknown 78 } 79 80 // SetSpanTags sets one or more tags on the given span according to the 81 // error. 82 func SetSpanTags(span opentracing.Span, err error, client bool) { 83 c := ErrorClass(err) 84 code := codes.Unknown 85 if s, ok := status.FromError(err); ok { 86 code = s.Code() 87 } 88 if value, ok := codeStrings[code]; ok { 89 span.SetTag(Status, value) 90 } else { 91 span.SetTag(Status, uint32(code)) 92 } 93 if value, ok := classStrings[c]; ok { 94 span.SetTag("response_class", value) 95 } else { 96 span.SetTag("response_class", string(c)) 97 } 98 99 if err == nil { 100 return 101 } 102 if client || c == ServerError { 103 ext.Error.Set(span, true) 104 } 105 }