From 72d3f4896a46a9b820fbb6955d738fac0f31b371 Mon Sep 17 00:00:00 2001 From: Kai Aoki Date: Tue, 12 Jul 2022 00:10:57 +0900 Subject: [PATCH 1/4] Update httplib.h use std::exception_ptr --- httplib.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/httplib.h b/httplib.h index 1c4db98..111276a 100644 --- a/httplib.h +++ b/httplib.h @@ -616,7 +616,7 @@ public: using Handler = std::function; using ExceptionHandler = - std::function; + std::function; enum class HandlerResponse { Handled, @@ -5733,7 +5733,8 @@ Server::process_request(Stream &strm, bool close_connection, routed = routing(req, res, strm); } catch (std::exception &e) { if (exception_handler_) { - exception_handler_(req, res, e); + auto ep = std::current_exception(); + exception_handler_(req, res, ep); routed = true; } else { res.status = 500; From d4ab2fa0e6a1f903a5f4be761d1f1ed5e4aaee8c Mon Sep 17 00:00:00 2001 From: Kai Aoki Date: Fri, 15 Jul 2022 01:45:10 +0900 Subject: [PATCH 2/4] fix double ref and case of exceptions that are not std::exception --- httplib.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/httplib.h b/httplib.h index 111276a..7647fed 100644 --- a/httplib.h +++ b/httplib.h @@ -616,7 +616,7 @@ public: using Handler = std::function; using ExceptionHandler = - std::function; + std::function; enum class HandlerResponse { Handled, @@ -5741,8 +5741,14 @@ Server::process_request(Stream &strm, bool close_connection, res.set_header("EXCEPTION_WHAT", e.what()); } } catch (...) { - res.status = 500; - res.set_header("EXCEPTION_WHAT", "UNKNOWN"); + if (exception_handler_) { + auto ep = std::current_exception(); + exception_handler_(req, res, ep); + routed = true; + } else { + res.status = 500; + res.set_header("EXCEPTION_WHAT", "UNKNOWN"); + } } #endif From 869f5bb2794c0c2fb458fae898e20c0f179ffc88 Mon Sep 17 00:00:00 2001 From: Kai Aoki Date: Fri, 15 Jul 2022 11:50:26 +0900 Subject: [PATCH 3/4] fix ExceptionHandlerTest.ContentLength --- test/test.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/test.cc b/test/test.cc index 3f94e58..6bd3330 100644 --- a/test/test.cc +++ b/test/test.cc @@ -1249,8 +1249,13 @@ TEST(ExceptionHandlerTest, ContentLength) { Server svr; svr.set_exception_handler([](const Request & /*req*/, Response &res, - std::exception &e) { - EXPECT_EQ("abc", std::string(e.what())); + std::exception_ptr ep) { + EXPECT_FALSE(ep == nullptr); + try{ + std::rethrow_exception(ep); + }catch(std::exception& e){ + EXPECT_EQ("abc", std::string(e.what())); + } res.status = 500; res.set_content("abcdefghijklmnopqrstuvwxyz", "text/html"); // <= Content-Length still 13 at this point From 07e614eef7c88daa734e5d32e050f1e7138a99db Mon Sep 17 00:00:00 2001 From: yhirose Date: Fri, 15 Jul 2022 17:32:38 -0400 Subject: [PATCH 4/4] clangformat and README update --- README.md | 14 +++++++++++--- test/test.cc | 6 ++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 48eb423..36acd2a 100644 --- a/README.md +++ b/README.md @@ -212,15 +212,23 @@ svr.set_error_handler([](const auto& req, auto& res) { The exception handler gets called if a user routing handler throws an error. ```cpp -svr.set_exception_handler([](const auto& req, auto& res, std::exception &e) { - res.status = 500; +svr.set_exception_handler([](const auto& req, auto& res, std::exception_ptr ep) { auto fmt = "

Error 500

%s

"; char buf[BUFSIZ]; - snprintf(buf, sizeof(buf), fmt, e.what()); + try { + std::rethrow_exception(ep); + } catch (std::exception &e) { + snprintf(buf, sizeof(buf), fmt, e.what()); + } catch (...) { // See the following NOTE + snprintf(buf, sizeof(buf), fmt, "Unknown Exception"); + } res.set_content(buf, "text/html"); + res.status = 500; }); ``` +NOTE: if you don't provide the `catch (...)` block for a rethrown exception pointer, an uncaught exception will end up causing the server crash. Be careful! + ### Pre routing handler ```cpp diff --git a/test/test.cc b/test/test.cc index 58dc5b2..6ca8497 100644 --- a/test/test.cc +++ b/test/test.cc @@ -1251,11 +1251,9 @@ TEST(ExceptionHandlerTest, ContentLength) { svr.set_exception_handler([](const Request & /*req*/, Response &res, std::exception_ptr ep) { EXPECT_FALSE(ep == nullptr); - try{ + try { std::rethrow_exception(ep); - }catch(std::exception& e){ - EXPECT_EQ("abc", std::string(e.what())); - } + } catch (std::exception &e) { EXPECT_EQ("abc", std::string(e.what())); } res.status = 500; res.set_content("abcdefghijklmnopqrstuvwxyz", "text/html"); // <= Content-Length still 13 at this point