github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/status/status.go (about) 1 /* 2 * 3 * Copyright 2017 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package status implements errors returned by gRPC. These errors are 20 // serialized and transmitted on the wire between server and client, and allow 21 // for additional data to be transmitted via the Details field in the status 22 // proto. gRPC service handlers should return an error created by this 23 // package, and gRPC clients should expect a corresponding error to be 24 // returned from the RPC call. 25 // 26 // This package upholds the invariants that a non-nil error may not 27 // contain an OK code, and an OK code must result in a nil error. 28 package status 29 30 import ( 31 "context" 32 "errors" 33 "fmt" 34 35 spb "google.golang.org/genproto/googleapis/rpc/status" 36 37 "github.com/hxx258456/ccgo/grpc/codes" 38 "github.com/hxx258456/ccgo/grpc/internal/status" 39 ) 40 41 // Status references google.golang.org/grpc/internal/status. It represents an 42 // RPC status code, message, and details. It is immutable and should be 43 // created with New, Newf, or FromProto. 44 // https://godoc.org/google.golang.org/grpc/internal/status 45 type Status = status.Status 46 47 // New returns a Status representing c and msg. 48 func New(c codes.Code, msg string) *Status { 49 return status.New(c, msg) 50 } 51 52 // Newf returns New(c, fmt.Sprintf(format, a...)). 53 func Newf(c codes.Code, format string, a ...interface{}) *Status { 54 return New(c, fmt.Sprintf(format, a...)) 55 } 56 57 // Error returns an error representing c and msg. If c is OK, returns nil. 58 func Error(c codes.Code, msg string) error { 59 return New(c, msg).Err() 60 } 61 62 // Errorf returns Error(c, fmt.Sprintf(format, a...)). 63 func Errorf(c codes.Code, format string, a ...interface{}) error { 64 return Error(c, fmt.Sprintf(format, a...)) 65 } 66 67 // ErrorProto returns an error representing s. If s.Code is OK, returns nil. 68 func ErrorProto(s *spb.Status) error { 69 return FromProto(s).Err() 70 } 71 72 // FromProto returns a Status representing s. 73 func FromProto(s *spb.Status) *Status { 74 return status.FromProto(s) 75 } 76 77 // FromError returns a Status representation of err. 78 // 79 // - If err was produced by this package or implements the method `GRPCStatus() 80 // *Status`, the appropriate Status is returned. 81 // 82 // - If err is nil, a Status is returned with codes.OK and no message. 83 // 84 // - Otherwise, err is an error not compatible with this package. In this 85 // case, a Status is returned with codes.Unknown and err's Error() message, 86 // and ok is false. 87 func FromError(err error) (s *Status, ok bool) { 88 if err == nil { 89 return nil, true 90 } 91 if se, ok := err.(interface { 92 GRPCStatus() *Status 93 }); ok { 94 return se.GRPCStatus(), true 95 } 96 return New(codes.Unknown, err.Error()), false 97 } 98 99 // Convert is a convenience function which removes the need to handle the 100 // boolean return value from FromError. 101 func Convert(err error) *Status { 102 s, _ := FromError(err) 103 return s 104 } 105 106 // Code returns the Code of the error if it is a Status error, codes.OK if err 107 // is nil, or codes.Unknown otherwise. 108 func Code(err error) codes.Code { 109 // Don't use FromError to avoid allocation of OK status. 110 if err == nil { 111 return codes.OK 112 } 113 if se, ok := err.(interface { 114 GRPCStatus() *Status 115 }); ok { 116 return se.GRPCStatus().Code() 117 } 118 return codes.Unknown 119 } 120 121 // FromContextError converts a context error or wrapped context error into a 122 // Status. It returns a Status with codes.OK if err is nil, or a Status with 123 // codes.Unknown if err is non-nil and not a context error. 124 func FromContextError(err error) *Status { 125 if err == nil { 126 return nil 127 } 128 if errors.Is(err, context.DeadlineExceeded) { 129 return New(codes.DeadlineExceeded, err.Error()) 130 } 131 if errors.Is(err, context.Canceled) { 132 return New(codes.Canceled, err.Error()) 133 } 134 return New(codes.Unknown, err.Error()) 135 }