* Copyright (c) 2024 Huawei Technologies Co., Ltd.
* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <mc/error.h>
#include <mc/error_engine.h>
#include <mc/exception.h>
#include <mc/fmt/format_dict.h>
#include <mc/json.h>
#include <mc/log.h>
#include <mc/string.h>
#include <string_view>
#include <unordered_map>
namespace mc {
error::error() = default;
error::error(const error_info& info) : mc::enable_shared_from_this<error>(), error_info(info) {
}
error::error(std::string_view name, std::string_view format, error_level level)
: mc::enable_shared_from_this<error>(), error_info(name, format, level) {
}
error::error(const error& other)
: mc::enable_shared_from_this<error>(other),
error_info(other.name, other.format, other.level) {
this->args = other.args;
if (other.prev_error) {
this->prev_error.reset(new error(*other.prev_error));
}
}
error::error(error&& other) noexcept = default;
error& error::operator=(error&& other) noexcept = default;
error_ptr error::from_exception(std::exception_ptr e) {
try {
std::rethrow_exception(e);
} catch (mc::exception& e) {
return from_exception(e);
} catch (std::exception& e) {
return from_exception(e);
} catch (...) {
return from_exception(mc::exception());
}
}
error_ptr error::from_exception(const mc::exception& e) {
auto err = mc::make_shared<error>();
err->set_name(e.name());
auto& msgs = e.messages();
if (!msgs.empty()) {
auto& msg = msgs.back();
err->set_format(msg.get_format_template());
err->set_level(msg.get_level());
err->set_args(msg.get_args());
}
return err;
}
error_ptr error::from_exception(const std::exception& e) {
return from_exception(mc::std_exception_wrapper::from_current_exception(e));
}
void error::to_exception(mc::exception& e) const {
e.set_name(this->name);
e.append_log(this->to_log_message());
}
error& error::operator=(const error& other) {
if (this != &other) {
mc::enable_shared_from_this<error>::operator=(other);
this->name = other.name;
this->format = other.format;
this->level = other.level;
this->args = other.args;
if (other.prev_error) {
this->prev_error.reset(new error(*other.prev_error));
}
}
return *this;
}
std::string_view error::get_name() const {
return this->name;
}
std::string_view error::get_format() const {
return this->format;
}
const mc::dict& error::get_args() const {
return args;
}
std::string error::get_message() const {
if (this->format.empty()) {
return {};
}
return mc::format_dict(this->format, args);
}
error_level error::get_level() const {
return this->level;
}
void error::set_level(error_level level) {
this->level = level;
}
void error::set_name(std::string_view name) {
this->name = name;
}
void error::set_format(std::string_view format) {
this->format = format;
}
void error::set_prev_error(error_ptr other) {
this->prev_error = std::move(other);
}
void error::reset() {
this->name = {};
this->format = {};
this->args.clear();
this->prev_error = nullptr;
}
error& error::set_args(const mc::dict& args) {
this->args = args;
return *this;
}
std::string error::to_string() const {
return mc::to_string(*this);
}
std::string error::to_string_format_inplace() const {
mc::dict error_data;
error_data["name"] = this->name;
error_data["format"] = get_message();
return error_data.to_string();
}
bool error::is_set() const {
if (!this->name.empty()) {
return true;
}
if (this->prev_error) {
return this->prev_error->is_set();
}
return false;
}
bool error::has_error(std::string_view name) const {
if (this->name == name) {
return true;
}
if (this->prev_error) {
return this->prev_error->has_error(name);
}
return false;
}
bool error::operator==(const error& other) const {
return this->name == other.name && this->format == other.format && this->args == other.args;
}
bool error::operator!=(const error& other) const {
return !(*this == other);
}
mc::log::message error::to_log_message() const {
return mc::log::message(
this->level,
mc::log::context("", std::string(this->name), 0),
std::string(this->format),
this->args);
}
error_with_owner::error_with_owner() {
}
error_with_owner::error_with_owner(std::string name, std::string format)
: m_name_owner(std::move(name)), m_format_owner(std::move(format)) {
this->name = m_name_owner;
this->format = m_format_owner;
}
bool get_error_format_args(std::string_view format, mc::dict& arg_names) {
return mc::fmt::get_format_args(format, arg_names);
}
}