• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2016 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_LIB_IOMGR_ERROR_H
20 #define GRPC_SRC_CORE_LIB_IOMGR_ERROR_H
21 
22 #include <grpc/support/port_platform.h>
23 
24 #include <inttypes.h>
25 #include <stdbool.h>
26 
27 #include "absl/status/status.h"
28 
29 #include <grpc/slice.h>
30 #include <grpc/status.h>
31 #include <grpc/support/log.h>
32 #include <grpc/support/time.h>
33 
34 #include "src/core/lib/debug/trace.h"
35 #include "src/core/lib/gpr/spinlock.h"
36 #include "src/core/lib/gprpp/crash.h"
37 #include "src/core/lib/gprpp/status_helper.h"
38 #include "src/core/lib/slice/slice_internal.h"
39 
40 /// Opaque representation of an error.
41 
42 typedef absl::Status grpc_error_handle;
43 
44 #define GRPC_ERROR_CREATE(desc) \
45   StatusCreate(absl::StatusCode::kUnknown, desc, DEBUG_LOCATION, {})
46 
47 absl::Status grpc_status_create(absl::StatusCode code, absl::string_view msg,
48                                 const grpc_core::DebugLocation& location,
49                                 size_t children_count, absl::Status* children);
50 
51 // Create an error that references some other errors.
52 #define GRPC_ERROR_CREATE_REFERENCING(desc, errs, count)                      \
53   grpc_status_create(absl::StatusCode::kUnknown, desc, DEBUG_LOCATION, count, \
54                      errs)
55 
56 // Consumes all the errors in the vector and forms a referencing error from
57 // them. If the vector is empty, return absl::OkStatus().
58 template <typename VectorType>
grpc_status_create_from_vector(const grpc_core::DebugLocation & location,absl::string_view desc,VectorType * error_list)59 static absl::Status grpc_status_create_from_vector(
60     const grpc_core::DebugLocation& location, absl::string_view desc,
61     VectorType* error_list) {
62   absl::Status error;
63   if (error_list->size() != 0) {
64     error = grpc_status_create(absl::StatusCode::kUnknown, desc, location,
65                                error_list->size(), error_list->data());
66     error_list->clear();
67   }
68   return error;
69 }
70 
71 #define GRPC_ERROR_CREATE_FROM_VECTOR(desc, error_list) \
72   grpc_status_create_from_vector(DEBUG_LOCATION, desc, error_list)
73 
74 absl::Status grpc_os_error(const grpc_core::DebugLocation& location, int err,
75                            const char* call_name);
76 
grpc_assert_never_ok(absl::Status error)77 inline absl::Status grpc_assert_never_ok(absl::Status error) {
78   GPR_ASSERT(!error.ok());
79   return error;
80 }
81 
82 /// create an error associated with errno!=0 (an 'operating system' error)
83 #define GRPC_OS_ERROR(err, call_name) \
84   grpc_assert_never_ok(grpc_os_error(DEBUG_LOCATION, err, call_name))
85 
86 absl::Status grpc_wsa_error(const grpc_core::DebugLocation& location, int err,
87                             absl::string_view call_name);
88 
89 /// windows only: create an error associated with WSAGetLastError()!=0
90 #define GRPC_WSA_ERROR(err, call_name) \
91   grpc_wsa_error(DEBUG_LOCATION, err, call_name)
92 
93 grpc_error_handle grpc_error_set_int(grpc_error_handle src,
94                                      grpc_core::StatusIntProperty which,
95                                      intptr_t value);
96 /// It is an error to pass nullptr as `p`. Caller should allocate a phony
97 /// intptr_t for `p`, even if the value of `p` is not used.
98 bool grpc_error_get_int(grpc_error_handle error,
99                         grpc_core::StatusIntProperty which, intptr_t* p);
100 grpc_error_handle grpc_error_set_str(grpc_error_handle src,
101                                      grpc_core::StatusStrProperty which,
102                                      absl::string_view str);
103 /// Returns false if the specified string is not set.
104 bool grpc_error_get_str(grpc_error_handle error,
105                         grpc_core::StatusStrProperty which, std::string* str);
106 
107 /// Add a child error: an error that is believed to have contributed to this
108 /// error occurring. Allows root causing high level errors from lower level
109 /// errors that contributed to them. The src error takes ownership of the
110 /// child error.
111 ///
112 /// Edge Conditions -
113 /// 1) If either of \a src or \a child is absl::OkStatus(), returns a reference
114 /// to the other argument. 2) If both \a src and \a child are absl::OkStatus(),
115 /// returns absl::OkStatus(). 3) If \a src and \a child point to the same error,
116 /// returns a single reference. (Note that, 2 references should have been
117 /// received to the error in this case.)
118 grpc_error_handle grpc_error_add_child(grpc_error_handle src,
119                                        grpc_error_handle child);
120 
121 bool grpc_log_error(const char* what, grpc_error_handle error, const char* file,
122                     int line);
grpc_log_if_error(const char * what,grpc_error_handle error,const char * file,int line)123 inline bool grpc_log_if_error(const char* what, grpc_error_handle error,
124                               const char* file, int line) {
125   return error.ok() ? true : grpc_log_error(what, error, file, line);
126 }
127 
128 #define GRPC_LOG_IF_ERROR(what, error) \
129   (grpc_log_if_error((what), (error), __FILE__, __LINE__))
130 
131 /// Helper class to get & set grpc_error_handle in a thread-safe fashion.
132 /// This could be considered as atomic<grpc_error_handle>.
133 class AtomicError {
134  public:
135   AtomicError() = default;
AtomicError(grpc_error_handle error)136   explicit AtomicError(grpc_error_handle error) { error_ = error; }
137 
138   AtomicError(const AtomicError&) = delete;
139   AtomicError& operator=(const AtomicError&) = delete;
140 
141   /// returns get() == absl::OkStatus()
ok()142   bool ok() {
143     gpr_spinlock_lock(&lock_);
144     bool ret = error_.ok();
145     gpr_spinlock_unlock(&lock_);
146     return ret;
147   }
148 
get()149   grpc_error_handle get() {
150     gpr_spinlock_lock(&lock_);
151     grpc_error_handle ret = error_;
152     gpr_spinlock_unlock(&lock_);
153     return ret;
154   }
155 
set(grpc_error_handle error)156   void set(grpc_error_handle error) {
157     gpr_spinlock_lock(&lock_);
158     error_ = error;
159     gpr_spinlock_unlock(&lock_);
160   }
161 
162  private:
163   grpc_error_handle error_;
164   gpr_spinlock lock_ = GPR_SPINLOCK_STATIC_INITIALIZER;
165 };
166 
167 #endif  // GRPC_SRC_CORE_LIB_IOMGR_ERROR_H
168