Logging with a custom terminate handler
How can I use a custom terminate handler to log information about an unhandled exception?
You can use a custom terminate handler to log information about an unhandled exception before terminating the program. Here's an example of how you can set up a custom terminate handler for logging:
#include <exception>
#include <iostream>
void customTerminateHandler() {
try {
std::exception_ptr exPtr =
std::current_exception();
if (exPtr) {
std::rethrow_exception(exPtr);
}
} catch (const std::exception& ex) {
std::cout << "Unhandled exception: "
<< ex.what() << '\n';
} catch (...) {
std::cout << "Unhandled unknown exception\n";
}
std::abort();
}
int main() {
std::set_terminate(customTerminateHandler);
try {
throw std::runtime_error(
"Something went wrong");
} catch (const std::logic_error& ex) {
// Catch and handle logic_error exceptions
}
}
Unhandled exception: Something went wrong
In this example:
- We define a custom terminate handler function
customTerminateHandler
. - Inside the handler, we retrieve the currently thrown exception using
std::current_exception()
. - If an exception pointer is obtained, we rethrow the exception to catch and log its details.
- We catch specific exception types (e.g.,
std::exception
) and log their error messages usingex.what()
. - For unknown exceptions, we log a generic message.
- Finally, we call
std::abort()
to terminate the program.
In the main()
function:
- We set the custom terminate handler using
std::set_terminate()
. - We intentionally throw an exception that is not caught by the provided catch block.
When the unhandled exception is thrown, the custom terminate handler is invoked, logging the exception details before terminating the program.
Using std::terminate()
and the noexcept
Specifier
This lesson explores the std::terminate()
function and noexcept
specifier, with particular focus on their interactions with move semantics.