2.4 KiB
title, order, status
| title | order | status |
|---|---|---|
| S14. Catch Exceptions | 33 | draft |
When a route handler throws, cpp-httplib keeps the server running and responds with 500. By default, though, very little of the error information reaches the client. set_exception_handler() lets you intercept exceptions and build your own response.
Basic usage
svr.set_exception_handler(
[](const httplib::Request &req, httplib::Response &res,
std::exception_ptr ep) {
try {
std::rethrow_exception(ep);
} catch (const std::exception &e) {
res.status = 500;
res.set_content(std::string("error: ") + e.what(), "text/plain");
} catch (...) {
res.status = 500;
res.set_content("unknown error", "text/plain");
}
});
The handler receives a std::exception_ptr. The idiomatic move is to rethrow it with std::rethrow_exception() and catch by type. You can vary status code and message based on the exception type.
Branch on custom exception types
If you throw your own exception types, you can map them to 400 or 404 responses.
struct NotFound : std::runtime_error {
using std::runtime_error::runtime_error;
};
struct BadRequest : std::runtime_error {
using std::runtime_error::runtime_error;
};
svr.set_exception_handler(
[](const auto &req, auto &res, std::exception_ptr ep) {
try {
std::rethrow_exception(ep);
} catch (const NotFound &e) {
res.status = 404;
res.set_content(e.what(), "text/plain");
} catch (const BadRequest &e) {
res.status = 400;
res.set_content(e.what(), "text/plain");
} catch (const std::exception &e) {
res.status = 500;
res.set_content("internal error", "text/plain");
}
});
Now throwing NotFound("user not found") inside a handler is enough to return 404. No per-handler try/catch needed.
Relationship with set_error_handler
set_exception_handler() runs the moment the exception is thrown. After that, if res.status is 4xx or 5xx, set_error_handler() also runs. The order is exception_handler → error_handler. Think of their roles as:
- Exception handler: interpret the exception, set the status and message
- Error handler: see the status and wrap it in the shared template
Note: Without an exception handler, cpp-httplib returns a default 500 response and the exception details never make it to logs. Always set one for anything you want to debug.