diff options
Diffstat (limited to 'vendor/google.golang.org/grpc/status/status.go')
-rw-r--r-- | vendor/google.golang.org/grpc/status/status.go | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/vendor/google.golang.org/grpc/status/status.go b/vendor/google.golang.org/grpc/status/status.go new file mode 100644 index 0000000..871dc4b --- /dev/null +++ b/vendor/google.golang.org/grpc/status/status.go | |||
@@ -0,0 +1,168 @@ | |||
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 | "errors" | ||
32 | "fmt" | ||
33 | |||
34 | "github.com/golang/protobuf/proto" | ||
35 | "github.com/golang/protobuf/ptypes" | ||
36 | spb "google.golang.org/genproto/googleapis/rpc/status" | ||
37 | "google.golang.org/grpc/codes" | ||
38 | ) | ||
39 | |||
40 | // statusError is an alias of a status proto. It implements error and Status, | ||
41 | // and a nil statusError should never be returned by this package. | ||
42 | type statusError spb.Status | ||
43 | |||
44 | func (se *statusError) Error() string { | ||
45 | p := (*spb.Status)(se) | ||
46 | return fmt.Sprintf("rpc error: code = %s desc = %s", codes.Code(p.GetCode()), p.GetMessage()) | ||
47 | } | ||
48 | |||
49 | func (se *statusError) status() *Status { | ||
50 | return &Status{s: (*spb.Status)(se)} | ||
51 | } | ||
52 | |||
53 | // Status represents an RPC status code, message, and details. It is immutable | ||
54 | // and should be created with New, Newf, or FromProto. | ||
55 | type Status struct { | ||
56 | s *spb.Status | ||
57 | } | ||
58 | |||
59 | // Code returns the status code contained in s. | ||
60 | func (s *Status) Code() codes.Code { | ||
61 | if s == nil || s.s == nil { | ||
62 | return codes.OK | ||
63 | } | ||
64 | return codes.Code(s.s.Code) | ||
65 | } | ||
66 | |||
67 | // Message returns the message contained in s. | ||
68 | func (s *Status) Message() string { | ||
69 | if s == nil || s.s == nil { | ||
70 | return "" | ||
71 | } | ||
72 | return s.s.Message | ||
73 | } | ||
74 | |||
75 | // Proto returns s's status as an spb.Status proto message. | ||
76 | func (s *Status) Proto() *spb.Status { | ||
77 | if s == nil { | ||
78 | return nil | ||
79 | } | ||
80 | return proto.Clone(s.s).(*spb.Status) | ||
81 | } | ||
82 | |||
83 | // Err returns an immutable error representing s; returns nil if s.Code() is | ||
84 | // OK. | ||
85 | func (s *Status) Err() error { | ||
86 | if s.Code() == codes.OK { | ||
87 | return nil | ||
88 | } | ||
89 | return (*statusError)(s.s) | ||
90 | } | ||
91 | |||
92 | // New returns a Status representing c and msg. | ||
93 | func New(c codes.Code, msg string) *Status { | ||
94 | return &Status{s: &spb.Status{Code: int32(c), Message: msg}} | ||
95 | } | ||
96 | |||
97 | // Newf returns New(c, fmt.Sprintf(format, a...)). | ||
98 | func Newf(c codes.Code, format string, a ...interface{}) *Status { | ||
99 | return New(c, fmt.Sprintf(format, a...)) | ||
100 | } | ||
101 | |||
102 | // Error returns an error representing c and msg. If c is OK, returns nil. | ||
103 | func Error(c codes.Code, msg string) error { | ||
104 | return New(c, msg).Err() | ||
105 | } | ||
106 | |||
107 | // Errorf returns Error(c, fmt.Sprintf(format, a...)). | ||
108 | func Errorf(c codes.Code, format string, a ...interface{}) error { | ||
109 | return Error(c, fmt.Sprintf(format, a...)) | ||
110 | } | ||
111 | |||
112 | // ErrorProto returns an error representing s. If s.Code is OK, returns nil. | ||
113 | func ErrorProto(s *spb.Status) error { | ||
114 | return FromProto(s).Err() | ||
115 | } | ||
116 | |||
117 | // FromProto returns a Status representing s. | ||
118 | func FromProto(s *spb.Status) *Status { | ||
119 | return &Status{s: proto.Clone(s).(*spb.Status)} | ||
120 | } | ||
121 | |||
122 | // FromError returns a Status representing err if it was produced from this | ||
123 | // package, otherwise it returns nil, false. | ||
124 | func FromError(err error) (s *Status, ok bool) { | ||
125 | if err == nil { | ||
126 | return &Status{s: &spb.Status{Code: int32(codes.OK)}}, true | ||
127 | } | ||
128 | if s, ok := err.(*statusError); ok { | ||
129 | return s.status(), true | ||
130 | } | ||
131 | return nil, false | ||
132 | } | ||
133 | |||
134 | // WithDetails returns a new status with the provided details messages appended to the status. | ||
135 | // If any errors are encountered, it returns nil and the first error encountered. | ||
136 | func (s *Status) WithDetails(details ...proto.Message) (*Status, error) { | ||
137 | if s.Code() == codes.OK { | ||
138 | return nil, errors.New("no error details for status with code OK") | ||
139 | } | ||
140 | // s.Code() != OK implies that s.Proto() != nil. | ||
141 | p := s.Proto() | ||
142 | for _, detail := range details { | ||
143 | any, err := ptypes.MarshalAny(detail) | ||
144 | if err != nil { | ||
145 | return nil, err | ||
146 | } | ||
147 | p.Details = append(p.Details, any) | ||
148 | } | ||
149 | return &Status{s: p}, nil | ||
150 | } | ||
151 | |||
152 | // Details returns a slice of details messages attached to the status. | ||
153 | // If a detail cannot be decoded, the error is returned in place of the detail. | ||
154 | func (s *Status) Details() []interface{} { | ||
155 | if s == nil || s.s == nil { | ||
156 | return nil | ||
157 | } | ||
158 | details := make([]interface{}, 0, len(s.s.Details)) | ||
159 | for _, any := range s.s.Details { | ||
160 | detail := &ptypes.DynamicAny{} | ||
161 | if err := ptypes.UnmarshalAny(any, detail); err != nil { | ||
162 | details = append(details, err) | ||
163 | continue | ||
164 | } | ||
165 | details = append(details, detail.Message) | ||
166 | } | ||
167 | return details | ||
168 | } | ||