2011-07-27 17 views
5

Niedawno zacząłem używać boost :: exception. Teraz chciałbym użyć boost :: errinfo_nested_exception, aby wydrukować informacje o przyczynie błędu. Problem polega na tym, że nie mogę wymyślić, jak uzyskać informacje od przyczyny. Próbowałem następujące bez powodzenia:Jak wyodrębnić informacje z boost :: errinfo_nested_exception?

#include <iostream> 
#include <boost/exception/all.hpp> 

struct myex : public virtual boost::exception {}; 

int main() 
{ 
    myex cause; 
    cause << boost::errinfo_file_name("causefile.cpp"); 

    try { 
     myex ex; 
     ex << boost::errinfo_nested_exception(boost::copy_exception(cause)); 
     throw ex; 
    } 
    catch (myex& e) { 
     // Here I would like to extract file name from cause and print 
     // it in a nice way, but I cant figure out what to do with a 
     // boost::exception_ptr. 
     const boost::exception_ptr* c = 
     boost::get_error_info<boost::errinfo_nested_exception>(e); 

     // I cant do this: 
     // const std::string* file = boost::get_error_info<boost::errinfo_file_name>(*c); 

     // Nor this: 
     // const std::string* file = boost::get_error_info<boost::errinfo_file_name>(**c); 

     // This works fine and the nested exception is there, but that's not what I want. 
     std::cout << boost::diagnostic_information(e) << std::endl; 
    } 

    return 0; 
} 

Odpowiedz

2

Trzeba rethrow zagnieżdżony wyjątek i zbadać że:

const boost::exception_ptr* c = 
    boost::get_error_info<boost::errinfo_nested_exception>(e); 
if(c) try { 
    boost::rethrow_exception(*c); 
} catch(boost::exception const& e) { // or a type derived from it 
    const std::string* file = boost::get_error_info<boost::errinfo_file_name>(e); 
    // ... 
} catch(...) { 
    // presumably you don't want the exception to escape if it is 
    // not derived from boost::exception 
} 

ja osobiście używać get_error_info owijkę, która zwraca wynik z boost::get_error_info<some_error_info>(e), lub jeśli nic nie zostanie znalezione, wynik get_error_info<some_error_info>(nested) (wywołanie rekursywne tutaj) lub 0, jeśli nie ma zagnieżdżonego wyjątku (lub nie jest error_info -enabled).

Alternatywnie/jako uzupełnienie można czynnik kodu sprawdzającego powyżej (różne catch klauzulami) w funkcji:

std::string const* // or return a tuple of what you examined etc. 
examine_exception() 
{ 
    try { 
     throw; // precondition: an exception is active 
    } catch(boost::exception const& e) { 
     // as above 
     return ...; 
    } 
} 
+0

nieco dziwne, trzeba go retrhow, ale myślę, że to obcość w impuls . Może ma to coś wspólnego z pisaniem na klawiaturze. W każdym razie to rozwiązało mój problem. ;) – ygram

+0

@ygram Pochodzi z tego, jak określono 'boost :: exception_ptr' - jego interfejs jest dość minimalistyczny, a jedynym sposobem na zrobienie czegokolwiek użytecznego z wyjątkiem * stored * (w przeciwieństwie do samego wskaźnika) jest ponowne wyrzucenie . Biorąc pod uwagę, że został przyjęty do 'std :: exception_ptr' i że języki pozwalają na rzucanie, np. 'int', to właściwie dość solidna konstrukcja. –

Powiązane problemy