Apache Arrow (C++)
A columnar in-memory analytics layer designed to accelerate big data.
status.h
Go to the documentation of this file.
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 //
5 // A Status encapsulates the result of an operation. It may indicate success,
6 // or it may indicate an error with an associated error message.
7 //
8 // Multiple threads can invoke const methods on a Status without
9 // external synchronization, but if any of the threads may call a
10 // non-const method, all threads accessing the same Status must use
11 // external synchronization.
12 
13 // Adapted from Apache Kudu, TensorFlow
14 
15 #ifndef ARROW_STATUS_H_
16 #define ARROW_STATUS_H_
17 
18 #include <cstring>
19 #include <iosfwd>
20 #include <string>
21 
22 #ifdef ARROW_EXTRA_ERROR_CONTEXT
23 #include <sstream>
24 #endif
25 
26 #include "arrow/util/macros.h"
27 #include "arrow/util/visibility.h"
28 
29 // Return the given status if it is not OK.
30 #define ARROW_RETURN_NOT_OK(s) \
31  do { \
32  ::arrow::Status _s = (s); \
33  if (ARROW_PREDICT_FALSE(!_s.ok())) { \
34  return _s; \
35  } \
36  } while (false)
37 
38 // If 'to_call' returns a bad status, CHECK immediately with a logged message
39 // of 'msg' followed by the status.
40 #define ARROW_CHECK_OK_PREPEND(to_call, msg) \
41  do { \
42  ::arrow::Status _s = (to_call); \
43  ARROW_CHECK(_s.ok()) << (msg) << ": " << _s.ToString(); \
44  } while (false)
45 
46 // If the status is bad, CHECK immediately, appending the status to the
47 // logged message.
48 #define ARROW_CHECK_OK(s) ARROW_CHECK_OK_PREPEND(s, "Bad status")
49 
50 namespace arrow {
51 
52 #ifdef ARROW_EXTRA_ERROR_CONTEXT
53 
54 #define RETURN_NOT_OK(s) \
55  do { \
56  Status _s = (s); \
57  if (ARROW_PREDICT_FALSE(!_s.ok())) { \
58  std::stringstream ss; \
59  ss << __FILE__ << ":" << __LINE__ << " code: " << #s << "\n" << _s.message(); \
60  return Status(_s.code(), ss.str()); \
61  } \
62  } while (0)
63 
64 #else
65 
66 #define RETURN_NOT_OK(s) \
67  do { \
68  Status _s = (s); \
69  if (ARROW_PREDICT_FALSE(!_s.ok())) { \
70  return _s; \
71  } \
72  } while (false)
73 
74 #endif // ARROW_EXTRA_ERROR_CONTEXT
75 
76 #define RETURN_NOT_OK_ELSE(s, else_) \
77  do { \
78  Status _s = (s); \
79  if (!_s.ok()) { \
80  else_; \
81  return _s; \
82  } \
83  } while (false)
84 
85 enum class StatusCode : char {
86  OK = 0,
87  OutOfMemory = 1,
88  KeyError = 2,
89  TypeError = 3,
90  Invalid = 4,
91  IOError = 5,
92  UnknownError = 9,
93  NotImplemented = 10,
94  SerializationError = 11,
95  PythonError = 12,
96  PlasmaObjectExists = 20,
98  PlasmaStoreFull = 22
99 };
100 
101 #if defined(__clang__)
102 // Only clang supports warn_unused_result as a type annotation.
103 class ARROW_MUST_USE_RESULT ARROW_EXPORT Status;
104 #endif
105 
106 class ARROW_EXPORT Status {
107  public:
108  // Create a success status.
109  Status() : state_(NULL) {}
110  ~Status() { delete state_; }
111 
112  Status(StatusCode code, const std::string& msg);
113 
114  // Copy the specified status.
115  Status(const Status& s);
116  void operator=(const Status& s);
117 
118  // Return a success status.
119  static Status OK() { return Status(); }
120 
121  // Return error status of an appropriate type.
122  static Status OutOfMemory(const std::string& msg) {
123  return Status(StatusCode::OutOfMemory, msg);
124  }
125 
126  static Status KeyError(const std::string& msg) {
127  return Status(StatusCode::KeyError, msg);
128  }
129 
130  static Status TypeError(const std::string& msg) {
131  return Status(StatusCode::TypeError, msg);
132  }
133 
134  static Status UnknownError(const std::string& msg) {
135  return Status(StatusCode::UnknownError, msg);
136  }
137 
138  static Status NotImplemented(const std::string& msg) {
139  return Status(StatusCode::NotImplemented, msg);
140  }
141 
142  static Status Invalid(const std::string& msg) {
143  return Status(StatusCode::Invalid, msg);
144  }
145 
146  static Status IOError(const std::string& msg) {
147  return Status(StatusCode::IOError, msg);
148  }
149 
150  static Status SerializationError(const std::string& msg) {
151  return Status(StatusCode::SerializationError, msg);
152  }
153 
154  static Status PlasmaObjectExists(const std::string& msg) {
155  return Status(StatusCode::PlasmaObjectExists, msg);
156  }
157 
158  static Status PlasmaObjectNonexistent(const std::string& msg) {
159  return Status(StatusCode::PlasmaObjectNonexistent, msg);
160  }
161 
162  static Status PlasmaStoreFull(const std::string& msg) {
163  return Status(StatusCode::PlasmaStoreFull, msg);
164  }
165 
166  // Returns true iff the status indicates success.
167  bool ok() const { return (state_ == NULL); }
168 
169  bool IsOutOfMemory() const { return code() == StatusCode::OutOfMemory; }
170  bool IsKeyError() const { return code() == StatusCode::KeyError; }
171  bool IsInvalid() const { return code() == StatusCode::Invalid; }
172  bool IsIOError() const { return code() == StatusCode::IOError; }
173  bool IsTypeError() const { return code() == StatusCode::TypeError; }
174  bool IsUnknownError() const { return code() == StatusCode::UnknownError; }
175  bool IsNotImplemented() const { return code() == StatusCode::NotImplemented; }
176  // An object could not be serialized or deserialized.
177  bool IsSerializationError() const { return code() == StatusCode::SerializationError; }
178  // An error is propagated from a nested Python function.
179  bool IsPythonError() const { return code() == StatusCode::PythonError; }
180  // An object with this object ID already exists in the plasma store.
181  bool IsPlasmaObjectExists() const { return code() == StatusCode::PlasmaObjectExists; }
182  // An object was requested that doesn't exist in the plasma store.
184  return code() == StatusCode::PlasmaObjectNonexistent;
185  }
186  // An object is too large to fit into the plasma store.
187  bool IsPlasmaStoreFull() const { return code() == StatusCode::PlasmaStoreFull; }
188 
189  // Return a string representation of this status suitable for printing.
190  // Returns the string "OK" for success.
191  std::string ToString() const;
192 
193  // Return a string representation of the status code, without the message
194  // text or posix code information.
195  std::string CodeAsString() const;
196 
197  StatusCode code() const { return ok() ? StatusCode::OK : state_->code; }
198 
199  std::string message() const { return ok() ? "" : state_->msg; }
200 
201  private:
202  struct State {
203  StatusCode code;
204  std::string msg;
205  };
206  // OK status has a `NULL` state_. Otherwise, `state_` points to
207  // a `State` structure containing the error code and message(s)
208  State* state_;
209 
210  void CopyFrom(const State* s);
211 };
212 
213 static inline std::ostream& operator<<(std::ostream& os, const Status& x) {
214  os << x.ToString();
215  return os;
216 }
217 
218 inline Status::Status(const Status& s)
219  : state_((s.state_ == NULL) ? NULL : new State(*s.state_)) {}
220 
221 inline void Status::operator=(const Status& s) {
222  // The following condition catches both aliasing (when this == &s),
223  // and the common case where both s and *this are ok.
224  if (state_ != s.state_) {
225  CopyFrom(s.state_);
226  }
227 }
228 
229 } // namespace arrow
230 
231 #endif // ARROW_STATUS_H_
bool IsPlasmaObjectNonexistent() const
Definition: status.h:183
StatusCode code() const
Definition: status.h:197
bool IsUnknownError() const
Definition: status.h:174
StatusCode
Definition: status.h:85
bool IsPlasmaObjectExists() const
Definition: status.h:181
static Status PlasmaObjectExists(const std::string &msg)
Definition: status.h:154
Status()
Definition: status.h:109
bool ok() const
Definition: status.h:167
void operator=(const Status &s)
Definition: status.h:221
#define ARROW_MUST_USE_RESULT
Definition: macros.h:58
bool IsOutOfMemory() const
Definition: status.h:169
static Status OK()
Definition: status.h:119
static Status KeyError(const std::string &msg)
Definition: status.h:126
static Status PlasmaObjectNonexistent(const std::string &msg)
Definition: status.h:158
static Status Invalid(const std::string &msg)
Definition: status.h:142
bool IsIOError() const
Definition: status.h:172
static Status IOError(const std::string &msg)
Definition: status.h:146
bool IsKeyError() const
Definition: status.h:170
static Status UnknownError(const std::string &msg)
Definition: status.h:134
std::string ToString() const
static Status TypeError(const std::string &msg)
Definition: status.h:130
bool IsSerializationError() const
Definition: status.h:177
bool IsTypeError() const
Definition: status.h:173
Top-level namespace for Apache Arrow C++ API.
Definition: allocator.h:29
bool IsPythonError() const
Definition: status.h:179
static Status OutOfMemory(const std::string &msg)
Definition: status.h:122
bool IsNotImplemented() const
Definition: status.h:175
~Status()
Definition: status.h:110
static Status NotImplemented(const std::string &msg)
Definition: status.h:138
bool IsPlasmaStoreFull() const
Definition: status.h:187
std::string message() const
Definition: status.h:199
static Status SerializationError(const std::string &msg)
Definition: status.h:150
bool IsInvalid() const
Definition: status.h:171
static Status PlasmaStoreFull(const std::string &msg)
Definition: status.h:162