blob: af2cffe985c032a98b05a4336da594e086772195 [file] [log] [blame]
khenaidoo5fc5cea2021-08-11 17:39:16 -04001/*
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.
28package status
29
30import (
31 "context"
32 "fmt"
33
34 spb "google.golang.org/genproto/googleapis/rpc/status"
35
36 "google.golang.org/grpc/codes"
37 "google.golang.org/grpc/internal/status"
38)
39
40// Status references google.golang.org/grpc/internal/status. It represents an
41// RPC status code, message, and details. It is immutable and should be
42// created with New, Newf, or FromProto.
43// https://godoc.org/google.golang.org/grpc/internal/status
44type Status = status.Status
45
46// New returns a Status representing c and msg.
47func New(c codes.Code, msg string) *Status {
48 return status.New(c, msg)
49}
50
51// Newf returns New(c, fmt.Sprintf(format, a...)).
52func Newf(c codes.Code, format string, a ...interface{}) *Status {
53 return New(c, fmt.Sprintf(format, a...))
54}
55
56// Error returns an error representing c and msg. If c is OK, returns nil.
57func Error(c codes.Code, msg string) error {
58 return New(c, msg).Err()
59}
60
61// Errorf returns Error(c, fmt.Sprintf(format, a...)).
62func Errorf(c codes.Code, format string, a ...interface{}) error {
63 return Error(c, fmt.Sprintf(format, a...))
64}
65
66// ErrorProto returns an error representing s. If s.Code is OK, returns nil.
67func ErrorProto(s *spb.Status) error {
68 return FromProto(s).Err()
69}
70
71// FromProto returns a Status representing s.
72func FromProto(s *spb.Status) *Status {
73 return status.FromProto(s)
74}
75
khenaidoo5cb0d402021-12-08 14:09:16 -050076// FromError returns a Status representation of err.
77//
78// - If err was produced by this package or implements the method `GRPCStatus()
79// *Status`, the appropriate Status is returned.
80//
81// - If err is nil, a Status is returned with codes.OK and no message.
82//
83// - Otherwise, err is an error not compatible with this package. In this
84// case, a Status is returned with codes.Unknown and err's Error() message,
85// and ok is false.
khenaidoo5fc5cea2021-08-11 17:39:16 -040086func FromError(err error) (s *Status, ok bool) {
87 if err == nil {
88 return nil, true
89 }
90 if se, ok := err.(interface {
91 GRPCStatus() *Status
92 }); ok {
93 return se.GRPCStatus(), true
94 }
95 return New(codes.Unknown, err.Error()), false
96}
97
98// Convert is a convenience function which removes the need to handle the
99// boolean return value from FromError.
100func Convert(err error) *Status {
101 s, _ := FromError(err)
102 return s
103}
104
105// Code returns the Code of the error if it is a Status error, codes.OK if err
106// is nil, or codes.Unknown otherwise.
107func Code(err error) codes.Code {
108 // Don't use FromError to avoid allocation of OK status.
109 if err == nil {
110 return codes.OK
111 }
112 if se, ok := err.(interface {
113 GRPCStatus() *Status
114 }); ok {
115 return se.GRPCStatus().Code()
116 }
117 return codes.Unknown
118}
119
120// FromContextError converts a context error into a Status. It returns a
121// Status with codes.OK if err is nil, or a Status with codes.Unknown if err is
122// non-nil and not a context error.
123func FromContextError(err error) *Status {
124 switch err {
125 case nil:
126 return nil
127 case context.DeadlineExceeded:
128 return New(codes.DeadlineExceeded, err.Error())
129 case context.Canceled:
130 return New(codes.Canceled, err.Error())
131 default:
132 return New(codes.Unknown, err.Error())
133 }
134}