Error Handling¶
Conduit’s APIs emit three types of messages for logging and error handling:
Message Type | Description |
---|---|
Info | General Information |
Warning | Recoverable Error |
Error | Fatal Error |
Default Error Handlers¶
Conduit provides a default handler for each message type:
Message Type | Default Action |
---|---|
Info | Prints the message to standard out |
Warning | Throws a C++ Exception (conduit::Error instance) |
Error | Throws a C++ Exception (conduit::Error instance) |
Using Custom Error Handlers¶
The conduit::utils namespace provides functions to override each of the three default handlers with a method that provides the following signature:
void my_handler(const std::string &msg,
const std::string &file,
int line)
{
// your handling code here ...
}
conduit::utils::set_error_handler(my_handler);
Here is an example that re-wires all three error handlers to print to standard out:
//-----------------------------------------------------------------------------
void my_info_handler(const std::string &msg,
const std::string &file,
int line)
{
std::cout << "[INFO] " << msg << std::endl;
}
void my_warning_handler(const std::string &msg,
const std::string &file,
int line)
{
std::cout << "[WARNING!] " << msg << std::endl;
}
void my_error_handler(const std::string &msg,
const std::string &file,
int line)
{
std::cout << "[ERROR!] " << msg << std::endl;
// errors are considered fatal, aborting or unwinding the
// call stack with an exception are the only viable options
throw conduit::Error(msg,file,line);
}
// rewire error handlers
conduit::utils::set_info_handler(my_info_handler);
conduit::utils::set_warning_handler(my_warning_handler);
conduit::utils::set_error_handler(my_error_handler);
// emit an example info message
CONDUIT_INFO("An info message");
Node n;
n["my_value"].set_float64(42.0);
// emit an example warning message
// using "as" for wrong type emits a warning, returns a default value (0.0)
float32 v = n["my_value"].as_float32();
// emit an example error message
try
{
// fetching a non-existant path from a const Node emits an error
const Node &n_my_value = n["my_value"];
n_my_value["bad"];
}
catch(conduit::Error &e)
{
// pass
}
[INFO] An info message
[WARNING!] Node::as_float32() const -- DataType float64 at path my_value does not equal expected DataType float32
[ERROR!] Cannot fetch_existing, Node(my_value) is not an object
Using Restoring Default Handlers¶
The default handlers are part of the conduit::utils interface, so you can restore them using:
// restore default handlers
conduit::utils::set_info_handler(conduit::utils::default_info_handler);
conduit::utils::set_warning_handler(conduit::utils::default_warning_handler);
conduit::utils::set_error_handler(conduit::utils::default_error_handler);
Accessing Current Handlers¶
You can access the currently active handlers using the conduit::utils::info_handler(), conduit::utils::warning_handler(), and conduit::utils::error_handler() methods. Here is an example that shows how to save the current handlers, temporarily restore the default handlers, execute an operation, and finally restore the saved handlers:
// store current handlers
conduit::utils::conduit_info_handler on_info = conduit::utils::info_handler();
conduit::utils::conduit_warning_handler on_warn = conduit::utils::warning_handler();
conduit::utils::conduit_error_handler on_error = conduit::utils::error_handler();
// temporarily restore default handlers
conduit::utils::set_info_handler(conduit::utils::default_info_handler);
conduit::utils::set_warning_handler(conduit::utils::default_warning_handler);
conduit::utils::set_error_handler(conduit::utils::default_error_handler);
// do something exciting ...
// done with excitement, reset to previously saved handlers
conduit::utils::set_info_handler(on_info);
conduit::utils::set_warning_handler(on_warn);
conduit::utils::set_error_handler(on_error);