| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| // Copyright (c) 2011 The LevelDB Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. See the AUTHORS file for names of contributors. | |
| // | |
| // A Status encapsulates the result of an operation. It may indicate success, | |
| // or it may indicate an error with an associated error message. | |
| // | |
| // Multiple threads can invoke const methods on a Status without | |
| // external synchronization, but if any of the threads may call a | |
| // non-const method, all threads accessing the same Status must use | |
| // external synchronization. | |
| // Adapted from Apache Arrow | |
| // https://github.com/apache/arrow/blob/apache-arrow-17.0.0/cpp/src/arrow/status.cc | |
| #include "paimon/status.h" | |
| #include <cassert> | |
| #include <cstdlib> | |
| #include <iostream> | |
| namespace paimon { | |
| Status::Status(StatusCode code, const std::string& msg) : Status::Status(code, msg, nullptr) {} | |
| Status::Status(StatusCode code, std::string msg, std::shared_ptr<StatusDetail> detail) { | |
| // should not construct ok status with message | |
| assert(code != StatusCode::OK); | |
| state_ = new State; | |
| state_->code = code; | |
| state_->msg = std::move(msg); | |
| if (detail != nullptr) { | |
| state_->detail = std::move(detail); | |
| } | |
| } | |
| void Status::CopyFrom(const Status& s) { | |
| delete state_; | |
| if (s.state_ == nullptr) { | |
| state_ = nullptr; | |
| } else { | |
| state_ = new State(*s.state_); | |
| } | |
| } | |
| std::string Status::CodeAsString() const { | |
| if (state_ == nullptr) { | |
| return "OK"; | |
| } | |
| return CodeAsString(code()); | |
| } | |
| std::string Status::CodeAsString(StatusCode code) { | |
| const char* type; | |
| switch (code) { | |
| case StatusCode::OK: | |
| type = "OK"; | |
| break; | |
| case StatusCode::OutOfMemory: | |
| type = "Out of memory"; | |
| break; | |
| case StatusCode::KeyError: | |
| type = "Key error"; | |
| break; | |
| case StatusCode::TypeError: | |
| type = "Type error"; | |
| break; | |
| case StatusCode::Invalid: | |
| type = "Invalid"; | |
| break; | |
| case StatusCode::IOError: | |
| type = "IOError"; | |
| break; | |
| case StatusCode::CapacityError: | |
| type = "Capacity error"; | |
| break; | |
| case StatusCode::IndexError: | |
| type = "Index error"; | |
| break; | |
| case StatusCode::Cancelled: | |
| type = "Cancelled"; | |
| break; | |
| case StatusCode::UnknownError: | |
| type = "Unknown error"; | |
| break; | |
| case StatusCode::NotImplemented: | |
| type = "NotImplemented"; | |
| break; | |
| case StatusCode::SerializationError: | |
| type = "Serialization error"; | |
| break; | |
| case StatusCode::NotExist: | |
| type = "Not exist"; | |
| break; | |
| case StatusCode::Exist: | |
| type = "Exist"; | |
| break; | |
| default: | |
| type = "Unknown"; | |
| break; | |
| } | |
| return std::string(type); | |
| } | |
| std::string Status::ToString() const { | |
| std::string result(CodeAsString()); | |
| if (state_ == nullptr) { | |
| return result; | |
| } | |
| result += ": "; | |
| result += state_->msg; | |
| if (state_->detail != nullptr) { | |
| result += ". Detail: "; | |
| result += state_->detail->ToString(); | |
| } | |
| return result; | |
| } | |
| void Status::Abort() const { | |
| Abort(std::string()); | |
| } | |
| void Status::Abort(const std::string& message) const { | |
| std::cerr << "-- Paimon Fatal Error --\n"; | |
| if (!message.empty()) { | |
| std::cerr << message << "\n"; | |
| } | |
| std::cerr << ToString() << std::endl; | |
| std::abort(); | |
| } | |
| #ifdef PAIMON_EXTRA_ERROR_CONTEXT | |
| void Status::AddContextLine(const char* filename, int line, const char* function_name, | |
| const char* expr) { | |
| assert(!ok() && "Cannot add context line to ok status"); | |
| std::stringstream ss; | |
| ss << "\nIn " << filename << ":" << line << ", function: " << function_name | |
| << ", code: " << expr; | |
| state_->msg += ss.str(); | |
| } | |
| #endif | |
| } // namespace paimon |