添加到ERROR_INFO标准::异常 [英] Adding error_info to std::exception

查看:153
本文介绍了添加到ERROR_INFO标准::异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我整合的boost ::例外到现有code。一些code的现在使用 BOOST_THROW_EXCEPTION ,但有些人可能还是抛出标准的的std ::例外

I'm integrating boost::exception into existing code. Some of the code now uses BOOST_THROW_EXCEPTION, but some might still throw standard std::exception.

我想在中间抓站点添加ERROR_INFO。根据文档,如果异常是的boost ::例外,我可以做到这一点:

I want to add error_info at an intermediary catch site. According to the docs, if the exception is a boost::exception, I can just do this:

try {
    do_something()
}
catch( boost::exception & e ) {
    e << boost::errinfo_file_name(file_name);
    throw;
}

但是,这将仅在信息添加到升压异常。我想将它添加到的std ::例外为好。什么是做到这一点的干净的方式?这里有一种方法,但它会导致一些code复制:

But that will only add the info to the boost exceptions. I want to add it to the std::exception as well. What's the cleanest way to do that? Here's one way, but it results in some code duplication:

try {
    do_something()
}
catch( boost::exception & e ) {
    e << boost::errinfo_file_name(file_name);
    throw;
}
catch( std::exception & e ) {
    throw enable_error_info(e) << boost::errinfo_file_name(file_name);
}

有没有这相当于一个方法,给我当前异常作为升压异常,或者创建一个升压例外出来,如果​​它不是一?

Is there a method that's equivalent to "give me the current exception as a boost exception, or create a boost exception out of it if it isn't one"?

修改的boost :: enable_error_info()确实有点那个,但返回原始异常的副本,其中切片脱的boost ::例外我捕捉异常的一部分。案例分析:<​​/ P>

EDIT: boost::enable_error_info() kinda does that but returns a copy of the original exception, which slices off the boost::exception part of the exception I'm catching. Case in point:

int main()
{
    try {
        try {
            BOOST_THROW_EXCEPTION( std::runtime_error( "foo" ) );
        }
        catch( std::exception & e ) {
            std::cerr << e.what() << std::endl; // "foo" 
            if( const char* const* function = boost::get_error_info<boost::throw_function>(e) ) std::cerr << *function << std::endl; // "int main()"
            throw boost::enable_error_info(e) << boost::errinfo_file_name("bar");
        }
    }
    catch( std::exception & e ) {
        std::cerr << e.what() << std::endl; // "std::exception" 
        if( const char* const* function = boost::get_error_info<boost::throw_function>(e) ) std::cerr << *function << std::endl; // NOTHING
    }

    return 0;
}

修改:我尝试使用的boost :: current_exception(),它太切片东西了。基本上,任何试图复制一个异常会松一些,因为造成的多重继承切片的数据。同样的原因,为什么文档说,你应该总是重新抛出使用而不是抛电子商务。所以,我的真正的不想承担任何复制,除非它是必要的。

EDIT: I tried using boost::current_exception(), and it slices things off too. Basically, any attempt to copy an exception will loose some of the data because of the slicing caused by multiple inheritance. Same reason as why the docs say you should always rethrow using throw instead of throw e. So I really don't want to incur any copying unless it's necessary.

在理想情况下,我想写出以下内容,其中 current_exception_as_boost_exception()返回参照当前异常,如果它已经是一个提振::例外,否则返回调用的boost :: enable_error_info 上的结果。

Ideally, I'd like to write the following, where current_exception_as_boost_exception() returns a reference to the current exception if it is already a boost::exception, otherwise returns the result of calling boost::enable_error_info on it.

try {
    do_something()
}
catch( std::exception & e ) {
    throw current_exception_as_boost_exception() << boost::errinfo_file_name(file_name);
}

难道这就是提振::函数enable_current_exception 是?这真的不清楚它的目的是什么,它​​不是在任何教程使用。

Is that what boost::enable_current_exception is for? It's really unclear what its purpose is, and it's not used in any of the tutorials.

推荐答案

下面是一个解决方案,我想要做什么。但是,如果感觉就像我在这里彻底改造的东西。是不是有一个内置的方式来达到同样的事情?

Here is a solution that does what I want. But if feels like I'm reinventing something here. Isn't there a built-in way to achieve the same thing?

struct rethrow
{
    rethrow()
    {
        try{ throw; }
        // Already a boost::exception
        catch( boost::exception& ) {} 
        // Something else. Make it a boost::exception
        catch( ... ) { ptr = boost::current_exception(); } 
    }

    template<class T> 
    rethrow const& operator<<( const T& t ) const
    {
        try
        {
            re();
        }
        catch( boost::exception& e )
        {
            e << t;
        }
        return *this;
    }

    ~rethrow()
    {
        re();
    }

private:
    void re() const
    {
        if( !ptr ) throw;
        else boost::rethrow_exception( ptr );
    }

    boost::exception_ptr ptr; 
};


int main()
{
    try {
        try {
            throw std::runtime_error( "foo" ); // or BOOST_THROW_EXCEPTION( std::runtime_error( "foo" ) );
        }
        catch( std::exception & e ) {
            rethrow() << boost::errinfo_file_name("bar");
        }
    }
    catch( std::exception & e ) {
        std::cerr << __LINE__ << ": caught " << e.what() << std::endl; // "caught foo"
        if( const char* const* function = boost::get_error_info<boost::throw_function>(e) ) std::cerr << __LINE__ << ": throw from " << *function << std::endl; // "throw from int main()" (when using BOOST_THROW_EXCEPTION)
        if( std::string const* fileName = boost::get_error_info<boost::errinfo_file_name>(e) ) std::cerr << __LINE__ << ": trying to open " << *fileName << std::endl; // "trying to open bar"
    }

    return 0;
}

这篇关于添加到ERROR_INFO标准::异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆