17

I have a callback function which is bound to a boost::asio::deadline_timer. Now the function is called when the timer is cancelled or it expires. Since I need to distinguish between this two cases I need to check the passed Error code. The basic code would be like this:

void CameraCommand::handleTimeout(const boost::system::error_code& error)
{
    std::cout << "\nError: " << error.message() << "\n";
    return;
}

Now when the Handler is called because the timer expired the error code is Success, when the timer is cancelled the error code is Operation canceled.

Now my question would be, how to appropriately check what happened?

Suggestion 1:

if( error.message() == "Success" )
{
     // Timer expired
}
else
{
     // Timer cancelled
}

Suggestion 2:

if( error.value() == 0 )
{
     // Timer expired
}
else
{
     // Timer cancelled
}

Now my question is - is there any way to compare the error byitself and not by value or by string? Something like ( this is made up now )

if ( error == boost::system::error::types::success )

Because what I don't like about the first suggestion is that I need to create a string just for check, which is kinda unnecessary in my opinion. The second way has the disadvantge that I need to look up all the error codes if I want to check for something other? So are there any enums or ways to check for the error or do I have one of the two suggested ways?

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
Toby
  • 3,815
  • 14
  • 51
  • 67

3 Answers3

22

Looking at the documentation, you can use the enum values:

switch( error.value() )
{
    case boost::system::errc::success:
    {
    }
    break;

    case boost::system::errc::operation_canceled:
    {
      // Timer cancelled
    }
    break;

    default:
    {
       // Assert unexpected case
    }
    break;
}
Sam Miller
  • 23,808
  • 4
  • 67
  • 87
Scott Langham
  • 58,735
  • 39
  • 131
  • 204
  • Hmm, I might have got this wrong. This says we should be comparing error_codes to error_conditions and should not use the value() for comparisons. http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-2.html – Scott Langham Jul 24 '15 at 09:46
  • 3
    This is incorrect. boost error_code has categories and values. The same value can exist in more than one category. You must check both. – Christopher Pisz Mar 23 '17 at 17:29
16

You can just use a boolean cast:

if ( error )
{ 
    // Timer has been cancelled - or some other error. If you just want information
    // about the error then you can output the message() of the error.
}
else
{
    ...
}

boost::error_code has a boolean operator for this, have a look here: http://www.boost.org/doc/libs/1_48_0/libs/system/doc/reference.html#Class-error_code

Nick
  • 25,026
  • 7
  • 51
  • 83
  • Okay, this would be appropriate for this particular problem, since I just want to determine if it has been cancelled or just expired, what would mean `if(!error)`, but how to check for a particular error? – Toby Feb 10 '12 at 08:59
  • One thing to note is that each part of BOOST will have its own set of error codes. Check out http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/error__basic_errors.html – Nick Feb 10 '12 at 09:08
  • 3
    IMHO `if (error.value() != boost::system::errc::success)` is more precise, more readable and **does not depend on the boolean operator override implementation** and therefore is programmed to an interface, not an implementation. – Martin Meeser Mar 06 '13 at 14:33
  • @MartinMeeser Thanks for the important point. `if (error.value() != boost::system::errc::success)` means it is an error? Or does it mean its not a an error? – TheWaterProgrammer Jan 14 '19 at 22:25
3

You can use a default constructed error_code:

if( error == boost::system::error_code() )
syffinx
  • 351
  • 4
  • 6