@@ -598,6 +598,9 @@ class Server {
598598public:
599599 using Handler = std::function<void (const Request &, Response &)>;
600600
601+ using ExceptionHandler =
602+ std::function<void (const Request &, Response &, std::exception &e)>;
603+
601604 enum class HandlerResponse {
602605 Handled,
603606 Unhandled,
@@ -652,6 +655,7 @@ class Server {
652655
653656 Server &set_error_handler (HandlerWithResponse handler);
654657 Server &set_error_handler (Handler handler);
658+ Server &set_exception_handler (ExceptionHandler handler);
655659 Server &set_pre_routing_handler (HandlerWithResponse handler);
656660 Server &set_post_routing_handler (Handler handler);
657661
@@ -762,6 +766,7 @@ class Server {
762766 HandlersForContentReader delete_handlers_for_content_reader_;
763767 Handlers options_handlers_;
764768 HandlerWithResponse error_handler_;
769+ ExceptionHandler exception_handler_;
765770 HandlerWithResponse pre_routing_handler_;
766771 Handler post_routing_handler_;
767772 Logger logger_;
@@ -4281,6 +4286,11 @@ inline Server &Server::set_error_handler(Handler handler) {
42814286 return *this ;
42824287}
42834288
4289+ inline Server &Server::set_exception_handler (ExceptionHandler handler) {
4290+ exception_handler_ = std::move (handler);
4291+ return *this ;
4292+ }
4293+
42844294inline Server &Server::set_pre_routing_handler (HandlerWithResponse handler) {
42854295 pre_routing_handler_ = std::move (handler);
42864296 return *this ;
@@ -4785,26 +4795,26 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm) {
47854795
47864796 if (req.method == " POST" ) {
47874797 if (dispatch_request_for_content_reader (
4788- req, res, std::move (reader),
4789- post_handlers_for_content_reader_)) {
4798+ req, res, std::move (reader),
4799+ post_handlers_for_content_reader_)) {
47904800 return true ;
47914801 }
47924802 } else if (req.method == " PUT" ) {
47934803 if (dispatch_request_for_content_reader (
4794- req, res, std::move (reader),
4795- put_handlers_for_content_reader_)) {
4804+ req, res, std::move (reader),
4805+ put_handlers_for_content_reader_)) {
47964806 return true ;
47974807 }
47984808 } else if (req.method == " PATCH" ) {
47994809 if (dispatch_request_for_content_reader (
4800- req, res, std::move (reader),
4801- patch_handlers_for_content_reader_)) {
4810+ req, res, std::move (reader),
4811+ patch_handlers_for_content_reader_)) {
48024812 return true ;
48034813 }
48044814 } else if (req.method == " DELETE" ) {
48054815 if (dispatch_request_for_content_reader (
4806- req, res, std::move (reader),
4807- delete_handlers_for_content_reader_)) {
4816+ req, res, std::move (reader),
4817+ delete_handlers_for_content_reader_)) {
48084818 return true ;
48094819 }
48104820 }
@@ -4835,22 +4845,14 @@ inline bool Server::routing(Request &req, Response &res, Stream &strm) {
48354845
48364846inline bool Server::dispatch_request (Request &req, Response &res,
48374847 const Handlers &handlers) {
4838- try {
4839- for (const auto &x : handlers) {
4840- const auto &pattern = x.first ;
4841- const auto &handler = x.second ;
4848+ for (const auto &x : handlers) {
4849+ const auto &pattern = x.first ;
4850+ const auto &handler = x.second ;
48424851
4843- if (std::regex_match (req.path , req.matches , pattern)) {
4844- handler (req, res);
4845- return true ;
4846- }
4852+ if (std::regex_match (req.path , req.matches , pattern)) {
4853+ handler (req, res);
4854+ return true ;
48474855 }
4848- } catch (const std::exception &ex) {
4849- res.status = 500 ;
4850- res.set_header (" EXCEPTION_WHAT" , ex.what ());
4851- } catch (...) {
4852- res.status = 500 ;
4853- res.set_header (" EXCEPTION_WHAT" , " UNKNOWN" );
48544856 }
48554857 return false ;
48564858}
@@ -5064,7 +5066,23 @@ Server::process_request(Stream &strm, bool close_connection,
50645066 }
50655067
50665068 // Rounting
5067- if (routing (req, res, strm)) {
5069+ bool routed = false ;
5070+ try {
5071+ routed = routing (req, res, strm);
5072+ } catch (std::exception & e) {
5073+ if (exception_handler_) {
5074+ exception_handler_ (req, res, e);
5075+ routed = true ;
5076+ } else {
5077+ res.status = 500 ;
5078+ res.set_header (" EXCEPTION_WHAT" , e.what ());
5079+ }
5080+ } catch (...) {
5081+ res.status = 500 ;
5082+ res.set_header (" EXCEPTION_WHAT" , " UNKNOWN" );
5083+ }
5084+
5085+ if (routed) {
50685086 if (res.status == -1 ) { res.status = req.ranges .empty () ? 200 : 206 ; }
50695087 return write_response_with_content (strm, close_connection, req, res);
50705088 } else {
0 commit comments