File indexing completed on 2025-08-27 08:47:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #pragma once
0016
0017 #include <cstring>
0018 #include <iosfwd>
0019 #include <memory>
0020 #include <string>
0021 #include <utility>
0022
0023 #include "arrow/util/compare.h"
0024 #include "arrow/util/macros.h"
0025 #include "arrow/util/string_builder.h"
0026 #include "arrow/util/visibility.h"
0027
0028 #ifdef ARROW_EXTRA_ERROR_CONTEXT
0029
0030
0031 # define ARROW_RETURN_IF_(condition, status, expr) \
0032 do { \
0033 if (ARROW_PREDICT_FALSE(condition)) { \
0034 ::arrow::Status _st = (status); \
0035 _st.AddContextLine(__FILE__, __LINE__, expr); \
0036 return _st; \
0037 } \
0038 } while (0)
0039
0040 #else
0041
0042 # define ARROW_RETURN_IF_(condition, status, _) \
0043 do { \
0044 if (ARROW_PREDICT_FALSE(condition)) { \
0045 return (status); \
0046 } \
0047 } while (0)
0048
0049 #endif
0050
0051 #define ARROW_RETURN_IF(condition, status) \
0052 ARROW_RETURN_IF_(condition, status, ARROW_STRINGIFY(status))
0053
0054
0055 #define ARROW_RETURN_NOT_OK(status) \
0056 do { \
0057 ::arrow::Status __s = ::arrow::internal::GenericToStatus(status); \
0058 ARROW_RETURN_IF_(!__s.ok(), __s, ARROW_STRINGIFY(status)); \
0059 } while (false)
0060
0061
0062 #define ARROW_WARN_NOT_OK(expr, warn_msg) \
0063 do { \
0064 ::arrow::Status _s = (expr); \
0065 if (ARROW_PREDICT_FALSE(!_s.ok())) { \
0066 _s.Warn(warn_msg); \
0067 } \
0068 } while (false)
0069
0070 #define RETURN_NOT_OK_ELSE(s, else_) \
0071 do { \
0072 ::arrow::Status _s = ::arrow::internal::GenericToStatus(s); \
0073 if (!_s.ok()) { \
0074 else_; \
0075 return _s; \
0076 } \
0077 } while (false)
0078
0079
0080 #ifndef RETURN_NOT_OK
0081 # define RETURN_NOT_OK(s) ARROW_RETURN_NOT_OK(s)
0082 #endif
0083
0084 namespace arrow {
0085 namespace internal {
0086 class StatusConstant;
0087 }
0088
0089 enum class StatusCode : char {
0090 OK = 0,
0091 OutOfMemory = 1,
0092 KeyError = 2,
0093 TypeError = 3,
0094 Invalid = 4,
0095 IOError = 5,
0096 CapacityError = 6,
0097 IndexError = 7,
0098 Cancelled = 8,
0099 UnknownError = 9,
0100 NotImplemented = 10,
0101 SerializationError = 11,
0102 RError = 13,
0103
0104 CodeGenError = 40,
0105 ExpressionValidationError = 41,
0106 ExecutionError = 42,
0107
0108 AlreadyExists = 45
0109 };
0110
0111
0112
0113 class ARROW_EXPORT StatusDetail {
0114 public:
0115 virtual ~StatusDetail() = default;
0116
0117
0118 virtual const char* type_id() const = 0;
0119
0120 virtual std::string ToString() const = 0;
0121
0122 bool operator==(const StatusDetail& other) const noexcept {
0123 return std::string(type_id()) == other.type_id() && ToString() == other.ToString();
0124 }
0125 };
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 class ARROW_EXPORT [[nodiscard]] Status : public util::EqualityComparable<Status>,
0136 public util::ToStringOstreamable<Status> {
0137 public:
0138
0139 constexpr Status() noexcept : state_(NULLPTR) {}
0140 ~Status() noexcept {
0141 if (ARROW_PREDICT_FALSE(state_ != NULL)) {
0142 if (!state_->is_constant) {
0143 DeleteState();
0144 }
0145 }
0146 }
0147
0148 Status(StatusCode code, const std::string& msg);
0149
0150 Status(StatusCode code, std::string msg, std::shared_ptr<StatusDetail> detail);
0151
0152
0153 inline Status(const Status& s);
0154 inline Status& operator=(const Status& s);
0155
0156
0157 inline Status(Status&& s) noexcept;
0158 inline Status& operator=(Status&& s) noexcept;
0159
0160 inline bool Equals(const Status& s) const;
0161
0162
0163 inline Status operator&(const Status& s) const noexcept;
0164 inline Status operator&(Status&& s) const noexcept;
0165 inline Status& operator&=(const Status& s) noexcept;
0166 inline Status& operator&=(Status&& s) noexcept;
0167
0168
0169 static Status OK() { return Status(); }
0170
0171 template <typename... Args>
0172 static Status FromArgs(StatusCode code, Args&&... args) {
0173 return Status(code, util::StringBuilder(std::forward<Args>(args)...));
0174 }
0175
0176 template <typename... Args>
0177 static Status FromDetailAndArgs(StatusCode code, std::shared_ptr<StatusDetail> detail,
0178 Args&&... args) {
0179 return Status(code, util::StringBuilder(std::forward<Args>(args)...),
0180 std::move(detail));
0181 }
0182
0183
0184 template <typename... Args>
0185 static Status OutOfMemory(Args&&... args) {
0186 return Status::FromArgs(StatusCode::OutOfMemory, std::forward<Args>(args)...);
0187 }
0188
0189
0190 template <typename... Args>
0191 static Status KeyError(Args&&... args) {
0192 return Status::FromArgs(StatusCode::KeyError, std::forward<Args>(args)...);
0193 }
0194
0195
0196 template <typename... Args>
0197 static Status TypeError(Args&&... args) {
0198 return Status::FromArgs(StatusCode::TypeError, std::forward<Args>(args)...);
0199 }
0200
0201
0202 template <typename... Args>
0203 static Status UnknownError(Args&&... args) {
0204 return Status::FromArgs(StatusCode::UnknownError, std::forward<Args>(args)...);
0205 }
0206
0207
0208
0209 template <typename... Args>
0210 static Status NotImplemented(Args&&... args) {
0211 return Status::FromArgs(StatusCode::NotImplemented, std::forward<Args>(args)...);
0212 }
0213
0214
0215 template <typename... Args>
0216 static Status Invalid(Args&&... args) {
0217 return Status::FromArgs(StatusCode::Invalid, std::forward<Args>(args)...);
0218 }
0219
0220
0221 template <typename... Args>
0222 static Status Cancelled(Args&&... args) {
0223 return Status::FromArgs(StatusCode::Cancelled, std::forward<Args>(args)...);
0224 }
0225
0226
0227 template <typename... Args>
0228 static Status IndexError(Args&&... args) {
0229 return Status::FromArgs(StatusCode::IndexError, std::forward<Args>(args)...);
0230 }
0231
0232
0233 template <typename... Args>
0234 static Status CapacityError(Args&&... args) {
0235 return Status::FromArgs(StatusCode::CapacityError, std::forward<Args>(args)...);
0236 }
0237
0238
0239 template <typename... Args>
0240 static Status IOError(Args&&... args) {
0241 return Status::FromArgs(StatusCode::IOError, std::forward<Args>(args)...);
0242 }
0243
0244
0245 template <typename... Args>
0246 static Status SerializationError(Args&&... args) {
0247 return Status::FromArgs(StatusCode::SerializationError, std::forward<Args>(args)...);
0248 }
0249
0250 template <typename... Args>
0251 static Status RError(Args&&... args) {
0252 return Status::FromArgs(StatusCode::RError, std::forward<Args>(args)...);
0253 }
0254
0255 template <typename... Args>
0256 static Status CodeGenError(Args&&... args) {
0257 return Status::FromArgs(StatusCode::CodeGenError, std::forward<Args>(args)...);
0258 }
0259
0260 template <typename... Args>
0261 static Status ExpressionValidationError(Args&&... args) {
0262 return Status::FromArgs(StatusCode::ExpressionValidationError,
0263 std::forward<Args>(args)...);
0264 }
0265
0266 template <typename... Args>
0267 static Status ExecutionError(Args&&... args) {
0268 return Status::FromArgs(StatusCode::ExecutionError, std::forward<Args>(args)...);
0269 }
0270
0271 template <typename... Args>
0272 static Status AlreadyExists(Args&&... args) {
0273 return Status::FromArgs(StatusCode::AlreadyExists, std::forward<Args>(args)...);
0274 }
0275
0276
0277 constexpr bool ok() const { return (state_ == NULLPTR); }
0278
0279
0280 constexpr bool IsOutOfMemory() const { return code() == StatusCode::OutOfMemory; }
0281
0282 constexpr bool IsKeyError() const { return code() == StatusCode::KeyError; }
0283
0284 constexpr bool IsInvalid() const { return code() == StatusCode::Invalid; }
0285
0286 constexpr bool IsCancelled() const { return code() == StatusCode::Cancelled; }
0287
0288 constexpr bool IsIOError() const { return code() == StatusCode::IOError; }
0289
0290 constexpr bool IsCapacityError() const { return code() == StatusCode::CapacityError; }
0291
0292 constexpr bool IsIndexError() const { return code() == StatusCode::IndexError; }
0293
0294 constexpr bool IsTypeError() const { return code() == StatusCode::TypeError; }
0295
0296 constexpr bool IsUnknownError() const { return code() == StatusCode::UnknownError; }
0297
0298 constexpr bool IsNotImplemented() const { return code() == StatusCode::NotImplemented; }
0299
0300 constexpr bool IsSerializationError() const {
0301 return code() == StatusCode::SerializationError;
0302 }
0303
0304 constexpr bool IsRError() const { return code() == StatusCode::RError; }
0305
0306 constexpr bool IsCodeGenError() const { return code() == StatusCode::CodeGenError; }
0307
0308 constexpr bool IsExpressionValidationError() const {
0309 return code() == StatusCode::ExpressionValidationError;
0310 }
0311
0312 constexpr bool IsExecutionError() const { return code() == StatusCode::ExecutionError; }
0313 constexpr bool IsAlreadyExists() const { return code() == StatusCode::AlreadyExists; }
0314
0315
0316
0317
0318 std::string ToString() const;
0319
0320
0321
0322
0323
0324 std::string ToStringWithoutContextLines() const;
0325
0326
0327
0328 std::string CodeAsString() const;
0329 static std::string CodeAsString(StatusCode);
0330
0331
0332 constexpr StatusCode code() const { return ok() ? StatusCode::OK : state_->code; }
0333
0334
0335 const std::string& message() const;
0336
0337
0338 const std::shared_ptr<StatusDetail>& detail() const;
0339
0340
0341
0342 Status WithDetail(std::shared_ptr<StatusDetail> new_detail) const {
0343 return Status(code(), message(), std::move(new_detail));
0344 }
0345
0346
0347
0348 template <typename... Args>
0349 Status WithMessage(Args&&... args) const {
0350 return FromArgs(code(), std::forward<Args>(args)...).WithDetail(detail());
0351 }
0352
0353 void Warn() const;
0354 void Warn(const std::string& message) const;
0355
0356 [[noreturn]] void Abort() const;
0357 [[noreturn]] void Abort(const std::string& message) const;
0358
0359 #ifdef ARROW_EXTRA_ERROR_CONTEXT
0360 void AddContextLine(const char* filename, int line, const char* expr);
0361 #endif
0362
0363 private:
0364 struct State {
0365 StatusCode code;
0366 bool is_constant;
0367 std::string msg;
0368 std::shared_ptr<StatusDetail> detail;
0369 };
0370
0371
0372 State* state_;
0373
0374 void DeleteState() noexcept {
0375
0376
0377 delete state_;
0378 }
0379 void CopyFrom(const Status& s);
0380 inline void MoveFrom(Status& s);
0381
0382 friend class internal::StatusConstant;
0383 };
0384
0385 void Status::MoveFrom(Status& s) {
0386 if (ARROW_PREDICT_FALSE(state_ != NULL)) {
0387 if (!state_->is_constant) {
0388 DeleteState();
0389 }
0390 }
0391 state_ = s.state_;
0392 s.state_ = NULLPTR;
0393 }
0394
0395 Status::Status(const Status& s) : state_{NULLPTR} { CopyFrom(s); }
0396
0397 Status& Status::operator=(const Status& s) {
0398
0399
0400 if (state_ != s.state_) {
0401 CopyFrom(s);
0402 }
0403 return *this;
0404 }
0405
0406 Status::Status(Status&& s) noexcept : state_(s.state_) { s.state_ = NULLPTR; }
0407
0408 Status& Status::operator=(Status&& s) noexcept {
0409 MoveFrom(s);
0410 return *this;
0411 }
0412
0413 bool Status::Equals(const Status& s) const {
0414 if (state_ == s.state_) {
0415 return true;
0416 }
0417
0418 if (ok() || s.ok()) {
0419 return false;
0420 }
0421
0422 if (detail() != s.detail()) {
0423 if ((detail() && !s.detail()) || (!detail() && s.detail())) {
0424 return false;
0425 }
0426 return *detail() == *s.detail();
0427 }
0428
0429 return code() == s.code() && message() == s.message();
0430 }
0431
0432
0433
0434
0435 Status Status::operator&(const Status& s) const noexcept {
0436 if (ok()) {
0437 return s;
0438 } else {
0439 return *this;
0440 }
0441 }
0442
0443 Status Status::operator&(Status&& s) const noexcept {
0444 if (ok()) {
0445 return std::move(s);
0446 } else {
0447 return *this;
0448 }
0449 }
0450
0451 Status& Status::operator&=(const Status& s) noexcept {
0452 if (ok() && !s.ok()) {
0453 CopyFrom(s);
0454 }
0455 return *this;
0456 }
0457
0458 Status& Status::operator&=(Status&& s) noexcept {
0459 if (ok() && !s.ok()) {
0460 MoveFrom(s);
0461 }
0462 return *this;
0463 }
0464
0465
0466 namespace internal {
0467
0468
0469
0470 inline const Status& GenericToStatus(const Status& st) { return st; }
0471 inline Status GenericToStatus(Status&& st) { return std::move(st); }
0472
0473 }
0474
0475 }