Opened 9 years ago

Closed 9 years ago

#9796 closed Bugs (invalid)

std::system_error cannot be catched after is rethrown with boost::rethrow_exception()

Reported by: anonymous Owned by: Emil Dotchevski
Milestone: To Be Determined Component: exception
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc:

Description

boost::rethrow_exception() loses information about the system_error exception type. See the following example code, which when compiled with g++ --std=c++11, displays exception caught instead of system error caught:

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


void do_something()
{
  try
  {
    // let's assume the following exception is thrown inside some
    // system library function...
    throw std::system_error(EDOM, std::system_category());
  }
  catch (...)
  {
    boost::rethrow_exception(boost::current_exception());
  }
}
int main()
{
   try
   {
    do_something();
   }
   catch (const std::system_error & ex)
   {
      std::cout << "system error caught\n";
   }
   catch (const std::exception & ex)
   {
      std::cerr << "exception caught\n";
   }
   return 0;
}

Change History (4)

comment:1 by Emil Dotchevski, 9 years ago

Resolution: invalid
Status: newclosed

I understand that in this case the throw site might not be in your code, but see http://www.boost.org/doc/libs/release/libs/exception/doc/enable_current_exception.html. If possible, use boost::throw_exception instead of throw.

comment:2 by anonymous, 9 years ago

As I wrote this throw is from a std::library function (like for example std::thread().detach();, see [trac does not allow me to add links, so find it on google by yourself]), so throw_exception cannot be used.

Besides if you replace std::system_error with for example std::logic_error, the code works - the logic_error is properly catched. This means that this bug is not invalid. Please reopen it, and fix it.

comment:3 by anonymous, 9 years ago

Resolution: invalid
Status: closedreopened

in reply to:  3 comment:4 by Emil Dotchevski, 9 years ago

Resolution: invalid
Status: reopenedclosed

From http://www.boost.org/doc/libs/release/libs/exception/doc/current_exception.html: "Whenever current_exception fails to properly copy the current exception object, it returns an exception_ptr to an object of type that is as close as possible to the original exception type, using unknown_exception as a final fallback." This is to say that your code must be prepared to deal with boost::current_exception failing to give you an object of the exact type.

(The std::logic_error exception is also not properly cloned which can lead to slicing. Similar support for std::system_error is more problematic because it isn't available in all implementations yet. Where it is available, in all likelihood std::current_exception is available as well, so just use that.)

Last edited 9 years ago by Emil Dotchevski (previous) (diff)
Note: See TracTickets for help on using tickets.