• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "src/core/lib/channel/status_util.h"
20 
21 #include <grpc/support/port_platform.h>
22 #include <string.h>
23 
24 #include <vector>
25 
26 #include "absl/strings/str_cat.h"
27 #include "absl/strings/str_join.h"
28 #include "src/core/util/useful.h"
29 
30 struct status_string_entry {
31   const char* str;
32   grpc_status_code status;
33 };
34 static const status_string_entry g_status_string_entries[] = {
35     {"OK", GRPC_STATUS_OK},
36     {"CANCELLED", GRPC_STATUS_CANCELLED},
37     {"UNKNOWN", GRPC_STATUS_UNKNOWN},
38     {"INVALID_ARGUMENT", GRPC_STATUS_INVALID_ARGUMENT},
39     {"DEADLINE_EXCEEDED", GRPC_STATUS_DEADLINE_EXCEEDED},
40     {"NOT_FOUND", GRPC_STATUS_NOT_FOUND},
41     {"ALREADY_EXISTS", GRPC_STATUS_ALREADY_EXISTS},
42     {"PERMISSION_DENIED", GRPC_STATUS_PERMISSION_DENIED},
43     {"UNAUTHENTICATED", GRPC_STATUS_UNAUTHENTICATED},
44     {"RESOURCE_EXHAUSTED", GRPC_STATUS_RESOURCE_EXHAUSTED},
45     {"FAILED_PRECONDITION", GRPC_STATUS_FAILED_PRECONDITION},
46     {"ABORTED", GRPC_STATUS_ABORTED},
47     {"OUT_OF_RANGE", GRPC_STATUS_OUT_OF_RANGE},
48     {"UNIMPLEMENTED", GRPC_STATUS_UNIMPLEMENTED},
49     {"INTERNAL", GRPC_STATUS_INTERNAL},
50     {"UNAVAILABLE", GRPC_STATUS_UNAVAILABLE},
51     {"DATA_LOSS", GRPC_STATUS_DATA_LOSS},
52 };
53 
grpc_status_code_from_string(const char * status_str,grpc_status_code * status)54 bool grpc_status_code_from_string(const char* status_str,
55                                   grpc_status_code* status) {
56   for (size_t i = 0; i < GPR_ARRAY_SIZE(g_status_string_entries); ++i) {
57     if (strcmp(status_str, g_status_string_entries[i].str) == 0) {
58       *status = g_status_string_entries[i].status;
59       return true;
60     }
61   }
62   return false;
63 }
64 
grpc_status_code_to_string(grpc_status_code status)65 const char* grpc_status_code_to_string(grpc_status_code status) {
66   switch (status) {
67     case GRPC_STATUS_OK:
68       return "OK";
69     case GRPC_STATUS_CANCELLED:
70       return "CANCELLED";
71     case GRPC_STATUS_UNKNOWN:
72       return "UNKNOWN";
73     case GRPC_STATUS_INVALID_ARGUMENT:
74       return "INVALID_ARGUMENT";
75     case GRPC_STATUS_DEADLINE_EXCEEDED:
76       return "DEADLINE_EXCEEDED";
77     case GRPC_STATUS_NOT_FOUND:
78       return "NOT_FOUND";
79     case GRPC_STATUS_ALREADY_EXISTS:
80       return "ALREADY_EXISTS";
81     case GRPC_STATUS_PERMISSION_DENIED:
82       return "PERMISSION_DENIED";
83     case GRPC_STATUS_RESOURCE_EXHAUSTED:
84       return "RESOURCE_EXHAUSTED";
85     case GRPC_STATUS_FAILED_PRECONDITION:
86       return "FAILED_PRECONDITION";
87     case GRPC_STATUS_ABORTED:
88       return "ABORTED";
89     case GRPC_STATUS_OUT_OF_RANGE:
90       return "OUT_OF_RANGE";
91     case GRPC_STATUS_UNIMPLEMENTED:
92       return "UNIMPLEMENTED";
93     case GRPC_STATUS_INTERNAL:
94       return "INTERNAL";
95     case GRPC_STATUS_UNAVAILABLE:
96       return "UNAVAILABLE";
97     case GRPC_STATUS_DATA_LOSS:
98       return "DATA_LOSS";
99     case GRPC_STATUS_UNAUTHENTICATED:
100       return "UNAUTHENTICATED";
101     default:
102       return "UNKNOWN";
103   }
104 }
105 
grpc_status_code_from_int(int status_int,grpc_status_code * status)106 bool grpc_status_code_from_int(int status_int, grpc_status_code* status) {
107   // The range of status code enum is [0, 16], 0 is OK, 16 is UNAUTHENTICATED.
108   if (status_int < GRPC_STATUS_OK || status_int > GRPC_STATUS_UNAUTHENTICATED) {
109     *status = GRPC_STATUS_UNKNOWN;
110     return false;
111   }
112   *status = static_cast<grpc_status_code>(status_int);
113   return true;
114 }
115 
116 namespace grpc_core {
117 
118 namespace internal {
119 
ToString() const120 std::string StatusCodeSet::ToString() const {
121   std::vector<absl::string_view> codes;
122   for (size_t i = 0; i < GPR_ARRAY_SIZE(g_status_string_entries); ++i) {
123     if (Contains(g_status_string_entries[i].status)) {
124       codes.emplace_back(g_status_string_entries[i].str);
125     }
126   }
127   return absl::StrCat("{", absl::StrJoin(codes, ","), "}");
128 }
129 
130 }  // namespace internal
131 
MaybeRewriteIllegalStatusCode(absl::Status status,absl::string_view source)132 absl::Status MaybeRewriteIllegalStatusCode(absl::Status status,
133                                            absl::string_view source) {
134   switch (status.code()) {
135     // The set of disallowed codes, as per
136     // https://github.com/grpc/proposal/blob/master/A54-restrict-control-plane-status-codes.md.
137     case absl::StatusCode::kInvalidArgument:
138     case absl::StatusCode::kNotFound:
139     case absl::StatusCode::kAlreadyExists:
140     case absl::StatusCode::kFailedPrecondition:
141     case absl::StatusCode::kAborted:
142     case absl::StatusCode::kOutOfRange:
143     case absl::StatusCode::kDataLoss: {
144       return absl::InternalError(
145           absl::StrCat("Illegal status code from ", source,
146                        "; original status: ", status.ToString()));
147     }
148     default:
149       return status;
150   }
151 }
152 
153 }  // namespace grpc_core
154