try { // Some code which might raise an arbitrary senf exception } catch (senf::ExceptionMixin & e) { e << "\handling user " << user; throw; }
This will add the user information to any senf exception thrown. The Exception is however not a stream. If you need to do more extensive formating, either use an intermediate string-stream or use Boost.Format:
try { // ... } catch (senf::ExceptionMixin & e) { e << boost::format("\n" "call id 0x%04x@%s") % id % address; }
senf::SystemException is thrown for all operating system errors (failures which result in the operating system setting the errno value). It is also derived from senf::Exception and can therefore be extended as well.
Defining your own exception classes derived from senf::Exception is very simple:
struct FooException : public senf::Exception { FooException() : senf::Exception("Foo hit the fan") {} };
If SENF is compiled in debug mode (SENF_DEBUG is defined), the exception message will automatically include a stack backtrace. For this to work, you need to add the -rdynamic
option to all link commands. This feature depends on gcc
and the GNU-libc.
To apply these features (extensibility, backtrace) to a non-senf exception, the non-senf exception can be wrapped and re-thrown.
void foo() { try { // ... code that might throw std::bad_cast or somelib::FooException } SENF_WRAP_EXC(std::bad_cast) SENF_WRAP_EXC(somelib::FooException) }
std::bad_cast
or as senf::ExceptionMixin as needed. It is safe, to wrap an exception twice (the macro will detect this case).
bar() { try { try { foo(); } catch (senf::ExceptionMixin & ex) { ex << "\n" "add this info"; } } catch (std::bad_cast const & ex) { std::cerr << ex.what() << std::endl; }
std::bad_cast
exceptionOr better, use addr2line to obtain that information when showing the backtrace when catched within Daemon (addr2line -fsiCe argv[0]
)
Add signal handlers for the bad signals which writes a backtrace to stderr and terminates. This should probably write out a raw backtrace without de-mangling or line-numbers since we don't want to mess with dynamic memory when the heap might be corrupted ... Another handler for e.g. SIGUSR2 is nice to show a debug backtrace on demand
Classes |
|
class | senf::ExceptionMixin |
Generic extensible exception mixin. More... |
|
class | senf::Exception |
Extensible exception base-class. More... |
|
class | senf::WrapException< BaseException > |
Wrapper for standard non-senf exceptions. More... |
|
class | senf::SystemException |
Exception handling standard UNIX errors (errno). More... |
|
Defines |
|
#define | SENF_WRAP_EXC(Ex) |
Wrap a non-senf exception. |
#define | ||||
SENF_WRAP_EXC | ( | Ex | ) | |
Value:
catch (Ex const & base) { \ if (dynamic_cast<senf::ExceptionMixin const *>(&base)) \ throw; \ else \ throw senf::WrapException<Ex>(base); \ }
This macro allows to wrap a non-senf exception adding functionality from ExceptionMixin using the WrapException template. For an example, see Exception classes.
Definition at line 220 of file Exception.hh.