1 // 2 // 3 // Copyright 2021 the 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 #ifndef GRPC_SRC_CORE_UTIL_STATUS_HELPER_H 20 #define GRPC_SRC_CORE_UTIL_STATUS_HELPER_H 21 22 #include <grpc/support/port_platform.h> 23 #include <stdint.h> 24 25 #include <string> 26 #include <vector> 27 28 #include "absl/status/status.h" 29 #include "absl/strings/string_view.h" 30 #include "absl/time/time.h" 31 #include "absl/types/optional.h" 32 #include "src/core/util/debug_location.h" 33 34 extern "C" { 35 struct google_rpc_Status; 36 struct upb_Arena; 37 } 38 39 #define GRPC_RETURN_IF_ERROR(expr) \ 40 do { \ 41 const absl::Status status = (expr); \ 42 if (!status.ok()) return status; \ 43 } while (0) 44 45 namespace grpc_core { 46 47 /// This enum should have the same value of grpc_error_ints 48 enum class StatusIntProperty { 49 /// __LINE__ from the call site creating the error 50 kFileLine, 51 /// stream identifier: for errors that are associated with an individual 52 /// wire stream 53 kStreamId, 54 /// grpc status code representing this error 55 // TODO(veblush): Remove this after grpc_error is replaced with absl::Status 56 kRpcStatus, 57 /// http2 error code associated with the error (see the HTTP2 RFC) 58 kHttp2Error, 59 /// File descriptor associated with this error 60 kFd, 61 /// chttp2: did the error occur while a write was in progress 62 kOccurredDuringWrite, 63 /// channel connectivity state associated with the error 64 ChannelConnectivityState, 65 /// LB policy drop 66 kLbPolicyDrop, 67 }; 68 69 /// This enum should have the same value of grpc_error_strs 70 enum class StatusStrProperty { 71 /// top-level textual description of this error 72 kDescription, 73 /// source file in which this error occurred 74 kFile, 75 /// peer that we were trying to communicate when this error occurred 76 kGrpcMessage, 77 }; 78 79 /// This enum should have the same value of grpc_error_times 80 enum class StatusTimeProperty { 81 /// timestamp of error creation 82 kCreated, 83 }; 84 85 /// Creates a status with given additional information 86 absl::Status StatusCreate(absl::StatusCode code, absl::string_view msg, 87 const DebugLocation& location, 88 std::vector<absl::Status> children); 89 90 /// Sets the int property to the status 91 void StatusSetInt(absl::Status* status, StatusIntProperty key, intptr_t value); 92 93 /// Gets the int property from the status 94 GRPC_MUST_USE_RESULT 95 absl::optional<intptr_t> StatusGetInt(const absl::Status& status, 96 StatusIntProperty key); 97 98 /// Sets the str property to the status 99 void StatusSetStr(absl::Status* status, StatusStrProperty key, 100 absl::string_view value); 101 102 /// Gets the str property from the status 103 GRPC_MUST_USE_RESULT absl::optional<std::string> StatusGetStr( 104 const absl::Status& status, StatusStrProperty key); 105 106 /// Sets the time property to the status 107 void StatusSetTime(absl::Status* status, StatusTimeProperty key, 108 absl::Time time); 109 110 /// Gets the time property from the status 111 GRPC_MUST_USE_RESULT absl::optional<absl::Time> StatusGetTime( 112 const absl::Status& status, StatusTimeProperty key); 113 114 /// Adds a child status to status 115 void StatusAddChild(absl::Status* status, absl::Status child); 116 117 /// Returns all children status from a status 118 GRPC_MUST_USE_RESULT std::vector<absl::Status> StatusGetChildren( 119 absl::Status status); 120 121 /// Returns a string representation from status 122 /// Error status will be like 123 /// STATUS[:MESSAGE] [{PAYLOADS[, children:[CHILDREN-STATUS-LISTS]]}] 124 /// e.g. 125 /// CANCELLATION:SampleMessage {errno:'2021', line:'54', children:[ABORTED]} 126 GRPC_MUST_USE_RESULT std::string StatusToString(const absl::Status& status); 127 128 /// Adds prefix to the message of status. 129 absl::Status AddMessagePrefix(absl::string_view prefix, absl::Status status); 130 131 namespace internal { 132 133 /// Builds a upb message, google_rpc_Status from a status 134 /// This is for internal implementation & test only 135 GRPC_MUST_USE_RESULT google_rpc_Status* StatusToProto( 136 const absl::Status& status, upb_Arena* arena); 137 138 /// Builds a status from a upb message, google_rpc_Status 139 /// This is for internal implementation & test only 140 absl::Status StatusFromProto(google_rpc_Status* msg); 141 142 /// Returns ptr that is allocated in the heap memory and the given status is 143 /// copied into. This ptr can be used to get Status later and should be 144 /// freed by StatusFreeHeapPtr. This can be 0 in case of OkStatus. 145 uintptr_t StatusAllocHeapPtr(absl::Status s); 146 147 /// Frees the allocated status at heap ptr. 148 void StatusFreeHeapPtr(uintptr_t ptr); 149 150 /// Get the status from a heap ptr. 151 absl::Status StatusGetFromHeapPtr(uintptr_t ptr); 152 153 /// Move the status from a heap ptr. (GetFrom & FreeHeap) 154 absl::Status StatusMoveFromHeapPtr(uintptr_t ptr); 155 156 } // namespace internal 157 158 } // namespace grpc_core 159 160 #endif // GRPC_SRC_CORE_UTIL_STATUS_HELPER_H 161