blob: 54d187186b8ff2317426a8c4c4246a8569f35fae [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
76// FromError returns a Status representing err if it was produced by this
77// package or has a method `GRPCStatus() *Status`.
78// If err is nil, a Status is returned with codes.OK and no message.
79// Otherwise, ok is false and a Status is returned with codes.Unknown and
80// the original error message.
81func FromError(err error) (s *Status, ok bool) {
82 if err == nil {
83 return nil, true
84 }
85 if se, ok := err.(interface {
86 GRPCStatus() *Status
87 }); ok {
88 return se.GRPCStatus(), true
89 }
90 return New(codes.Unknown, err.Error()), false
91}
92
93// Convert is a convenience function which removes the need to handle the
94// boolean return value from FromError.
95func Convert(err error) *Status {
96 s, _ := FromError(err)
97 return s
98}
99
100// Code returns the Code of the error if it is a Status error, codes.OK if err
101// is nil, or codes.Unknown otherwise.
102func Code(err error) codes.Code {
103 // Don't use FromError to avoid allocation of OK status.
104 if err == nil {
105 return codes.OK
106 }
107 if se, ok := err.(interface {
108 GRPCStatus() *Status
109 }); ok {
110 return se.GRPCStatus().Code()
111 }
112 return codes.Unknown
113}
114
115// FromContextError converts a context error into a Status. It returns a
116// Status with codes.OK if err is nil, or a Status with codes.Unknown if err is
117// non-nil and not a context error.
118func FromContextError(err error) *Status {
119 switch err {
120 case nil:
121 return nil
122 case context.DeadlineExceeded:
123 return New(codes.DeadlineExceeded, err.Error())
124 case context.Canceled:
125 return New(codes.Canceled, err.Error())
126 default:
127 return New(codes.Unknown, err.Error())
128 }
129}