2011-07-27 26 views
5

Gần đây tôi đã bắt đầu sử dụng boost :: exception. Bây giờ tôi muốn sử dụng boost :: errinfo_nested_exception để in thông tin về nguyên nhân của lỗi. Vấn đề là tôi không thể tìm ra cách lấy thông tin từ nguyên nhân. Tôi đã thử những điều sau đây mà không thành công:Làm cách nào để trích xuất bất kỳ thông tin nào từ tăng :: 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; 
} 

Trả lời

2

Bạn cần phải rethrow ngoại trừ lồng nhau và xem xét rằng:

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 
} 

Cá nhân tôi sử dụng một wrapper get_error_info trả về kết quả của boost::get_error_info<some_error_info>(e) hoặc nếu không tìm thấy kết quả của get_error_info<some_error_info>(nested) (gọi lại đệ quy tại đây) hoặc 0 nếu không có ngoại lệ lồng nhau (hoặc không phải là error_info -kích hoạt).

Ngoài ra/như một sự bổ sung, bạn có thể yếu tố mã kiểm tra phía trên (khác nhau catch khoản) trong một chức năng:

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

Một chút lạ cần phải retrhow nó, nhưng tôi đoán đó là một lạ trong thúc đẩy . Có thể nó có liên quan đến việc gõ. Dù sao, nó giải quyết được vấn đề của tôi. ;) – ygram

+0

@ygram Nó xuất phát từ cách 'boost :: exception_ptr' được chỉ định - giao diện của nó khá tối giản, và cách duy nhất để làm bất cứ điều gì hữu ích với ngoại lệ * được lưu trữ * (trái ngược với chính con trỏ) là rethrow . Do nó được chấp nhận vào 'std :: exception_ptr' và các ngôn ngữ cho phép ném ví dụ 'int', nó thực sự là một thiết kế khá chắc chắn. –

Các vấn đề liên quan