public
Last active

Code sketch of a mechanism for attaching additional context to exceptions

  • Download Gist
econtext.cpp
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#include "econtext.h"
 
__thread std::vector<ExceptionContextItem> currentContext;
 
typedef void (*cxa_throw_type)(void *, void *, void (*) (void *));
static cxa_throw_type orig_cxa_throw = 0;
static void load_orig_throw_code()
{
orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw");
}
extern "C"
void __cxa_throw (void *thrown_exception, void *pvtinfo, void (*dest)(void *)) {
if (!orig_cxa_throw)
load_orig_throw_code();
 
currentContext.clear();
orig_cxa_throw(thrown_exception, pvtinfo, dest);
}
econtext.hpp
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#ifndef _ECONTEXT_HPP
#define _ECONTEXT_HPP
 
#define EXCEPTION_CONTEXT("row", x) \
scoped_exception_context<typeof(x)> ("row", &x);
 
template<typename T>
struct scoped_exception_context
{
public:
scoped_exception_context(const char* name, T* val) {
}
~scoped_exception_context() {
if (std::uncaught_exception()) {
currentContext.push_back(name, boost::lexical_cast<std::string>(val));
}
}
private:
const char* name;
T* val;
};
 
struct ExceptionContextItem {
const char * name;
std::string value;
};
 
__thread std::vector<ExceptionContextItem> currentContext;
 
#endif // _ECONTEXT_HPP
example.cpp
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
try {
size_t row = 0, col = 0;
EXCEPTION_CONTEXT("row", row);
EXCEPTION_CONTEXT("col", col);
for (row = 0; row < row_count; row++)
for (col = 0; col < col_count; col++) {
EXCEPTION_CONTEXT("contents", data[row][col])
if (!validate(data[row][col]))
throw validation_failed();
}
}
catch (validation_failed&)
{
dialog("Loading simulation failed because cell " + context["row"] + ", " + context["col"]
+ " of " + context["filename"] + " contains '" + context["contents"] + "' when it"
"should contain a number");
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.