[C++-sig] question on boost.python exception mechanisms

Holger Joukl Holger.Joukl at LBBW.de
Thu Apr 18 11:13:38 CEST 2013


Before trying out Niall's wealth of suggestions, just to fix up my own
erroneous example:

> From: Holger Joukl <Holger.Joukl at LBBW.de>
> A bit of a simplified example version using Boost's partial C++11
exception
> support
> would then be s.th. like:
>
> 0 $ cat dispatch_main_exception_map.cpp
> // File: dispatch_main_exception_map.cpp
>
> #include <iostream>
> [...]
> // this callback raises an exception, catches it and stores it in the
> // global (thread, exception)-map
> void guarded_callback_with_exception(cb_arg_t arg) {
>     std::cout << "--> guarded exception-throwing CPP callback" << arg <<
> std::endl;
>     try {
>         throw std::runtime_error("throwing up");
>     } catch (...) {
>         std::cout << "storing exception in exception map" << std::endl;
>         pthread_t current_thread = pthread_self();
>         exception_map[current_thread] = boost::current_exception();
>         exception_map.erase(current_thread);
> [...]
          ^^^^^^^^^^^^^^^^^^^
                  |
This defeats the purpose, of course, and rather needs to be put where the
re-throw takes place.
Shouldn't make late additions and then overlook the missing output.

$ cat dispatch_main_exception_map.cpp
// File: dispatch_main_exception_map.cpp

#include <iostream>
#include <exception>
#include <stdexcept>
#include <pthread.h>
// header-only:
#include <boost/unordered_map.hpp>
// header-only:
#include <boost/exception_ptr.hpp>
#include "dispatch.h"


// the global per-thread exception storage
boost::unordered_map<pthread_t, boost::exception_ptr> exception_map;


void callback(cb_arg_t arg) {
    std::cout << "--> CPP callback" << arg << std::endl;
    std::cout << "<-- CPP callback" << arg << std::endl;
}

// this callback raises an exception
void callback_with_exception(cb_arg_t arg) {
    std::cout << "--> exception-throwing CPP callback" << arg << std::endl;
    throw std::runtime_error("throwing up");
    std::cout << "<-- exception-throwing CPP callback" << arg << std::endl;
}


// this callback raises an exception, catches it and stores it in the
// global (thread, exception)-map
void guarded_callback_with_exception(cb_arg_t arg) {
    std::cout << "--> guarded exception-throwing CPP callback" << arg <<
std::endl;
    try {
        throw std::runtime_error("throwing up");
    } catch (...) {
        std::cout << "storing exception in exception map" << std::endl;
        pthread_t current_thread = pthread_self();
        exception_map[current_thread] = boost::current_exception();
    }
    std::cout << "<-- guarded exception-throwing CPP callback" << arg <<
std::endl;
}


int main(void) {
    std::cout << "--> CPP main" << std::endl;
    cb_arg_t s = "CPP main callback argument";

    std::cout << std::endl;
    invoke(&callback, s);

    std::cout << std::endl;
    invoke(&guarded_callback_with_exception, s);
    pthread_t current_thread = pthread_self();
    if (exception_map.find(current_thread) != exception_map.end()) {
        try {
            std::cout << "rethrowing exception from exception map" <<
std::endl;
            boost::exception_ptr current_exception(exception_map
[current_thread]);
            exception_map.erase(current_thread);
            boost::rethrow_exception(current_exception);
        } catch (const std::exception& exc) {
            std::cout << "caught callback exception: " << exc.what() <<
std::endl;
        }
    }

    std::cout << std::endl;
    try {
        invoke(&callback_with_exception, s);
    } catch (const std::exception& exc) {
        std::cout << "caught callback exception: " << exc.what() <<
std::endl;
    }

    std::cout << std::endl;
    std::cout << "<-- CPP main" << std::endl;
    return 0;
}
0 $ ./a.out
--> CPP main

--> invoke(136888, CPP main callback argument)
--> CPP callbackCPP main callback argument
<-- CPP callbackCPP main callback argument
<-- invoke(136888, CPP main callback argument)

--> invoke(137608, CPP main callback argument)
--> guarded exception-throwing CPP callbackCPP main callback argument
storing exception in exception map
<-- guarded exception-throwing CPP callbackCPP main callback argument
<-- invoke(137608, CPP main callback argument)
rethrowing exception from exception map
caught callback exception: throwing up

--> invoke(137112, CPP main callback argument)
--> exception-throwing CPP callbackCPP main callback argument
caught callback exception: throwing up

<-- CPP main

Holger

Landesbank Baden-Wuerttemberg
Anstalt des oeffentlichen Rechts
Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz
HRA 12704
Amtsgericht Stuttgart



More information about the Cplusplus-sig mailing list