properly handle unexpected exceptions
Prior code followed a poorly explained example and then would
just re-throw the exception without actually catching it. The
new code (while specific to gcc and clang) will log the unexpected
exception type so it will not be fatal.
Tested: throw an std::string in a handler and see that it is not fatal.
MESSAGE=Handler failed to catch exception
EXCEPTION=std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >
Change-Id: I4734aba8ea6fb02ad8ce54be55e860d2b4c6576c
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/include/ipmid/handler.hpp b/include/ipmid/handler.hpp
index 3b40762..27ce370 100644
--- a/include/ipmid/handler.hpp
+++ b/include/ipmid/handler.hpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
#pragma once
+#include <cxxabi.h>
+
#include <algorithm>
#include <boost/asio/spawn.hpp>
#include <boost/callable_traits.hpp>
@@ -87,6 +89,13 @@
}
};
+static inline const char* currentExceptionType()
+{
+ int status;
+ return abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), 0,
+ 0, &status);
+}
+
/**
* @brief Handler base class for dealing with IPMI request/response
*
@@ -282,24 +291,13 @@
}
catch (...)
{
- std::exception_ptr eptr;
- try
- {
- eptr = std::current_exception();
- if (eptr)
- {
- std::rethrow_exception(eptr);
- }
- }
- catch (const std::exception& e)
- {
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Handler failed to catch exception",
- phosphor::logging::entry("EXCEPTION=%s", e.what()),
- phosphor::logging::entry("NETFN=%x", request->ctx->netFn),
- phosphor::logging::entry("CMD=%x", request->ctx->cmd));
- return errorResponse(request, ccUnspecifiedError);
- }
+ const char* what = currentExceptionType();
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Handler failed to catch exception",
+ phosphor::logging::entry("EXCEPTION=%s", what),
+ phosphor::logging::entry("NETFN=%x", request->ctx->netFn),
+ phosphor::logging::entry("CMD=%x", request->ctx->cmd));
+ return errorResponse(request, ccUnspecifiedError);
}
response->cc = std::get<0>(result);
@@ -395,24 +393,13 @@
}
catch (...)
{
- std::exception_ptr eptr;
- try
- {
- eptr = std::current_exception();
- if (eptr)
- {
- std::rethrow_exception(eptr);
- }
- }
- catch (const std::exception& e)
- {
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Handler failed to catch exception",
- phosphor::logging::entry("EXCEPTION=%s", e.what()),
- phosphor::logging::entry("NETFN=%x", request->ctx->netFn),
- phosphor::logging::entry("CMD=%x", request->ctx->cmd));
- return errorResponse(request, ccUnspecifiedError);
- }
+ const char* what = currentExceptionType();
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Handler failed to catch exception",
+ phosphor::logging::entry("EXCEPTION=%s", what),
+ phosphor::logging::entry("NETFN=%x", request->ctx->netFn),
+ phosphor::logging::entry("CMD=%x", request->ctx->cmd));
+ return errorResponse(request, ccUnspecifiedError);
}
response->cc = ccRet;
response->payload.resize(len);
@@ -498,24 +485,13 @@
}
catch (...)
{
- std::exception_ptr eptr;
- try
- {
- eptr = std::current_exception();
- if (eptr)
- {
- std::rethrow_exception(eptr);
- }
- }
- catch (const std::exception& e)
- {
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "Handler failed to catch exception",
- phosphor::logging::entry("EXCEPTION=%s", e.what()),
- phosphor::logging::entry("NETFN=%x", request->ctx->netFn),
- phosphor::logging::entry("CMD=%x", request->ctx->cmd));
- return errorResponse(request, ccUnspecifiedError);
- }
+ const char* what = currentExceptionType();
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Handler failed to catch exception",
+ phosphor::logging::entry("EXCEPTION=%s", what),
+ phosphor::logging::entry("NETFN=%x", request->ctx->netFn),
+ phosphor::logging::entry("CMD=%x", request->ctx->cmd));
+ return errorResponse(request, ccUnspecifiedError);
}
response->cc = ccRet;
response->payload.resize(len);
diff --git a/ipmid-new.cpp b/ipmid-new.cpp
index 88a51b5..be809cf 100644
--- a/ipmid-new.cpp
+++ b/ipmid-new.cpp
@@ -606,17 +606,10 @@
}
catch (...)
{
- std::exception_ptr eptr = std::current_exception();
- try
- {
- std::rethrow_exception(eptr);
- }
- catch (std::exception& e)
- {
- log<level::ERR>("ERROR opening IPMI provider",
- entry("PROVIDER=%s", name.c_str()),
- entry("ERROR=%s", e.what()));
- }
+ const char* what = currentExceptionType();
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "ERROR opening IPMI provider",
+ entry("PROVIDER=%s", name.c_str()), entry("ERROR=%s", what));
}
if (!isOpen())
{