How to use the 1st argument of the boost::asio::signal_set::async_wait's handler?

132 Views Asked by At
void handler(boost::system::error_code const& e, int s)
{
  if (!e) { /* I see it */ }
  else { /* but I don't understand which situations the case occurs in. */ }
}

What errors can generally happen in an application for the case? Thanks for your explaination.

1

There are 1 best solutions below

0
On

Error codes are like a "qualified enum": a tuple of (value, category) where category distinguishes different error domains.

You can use code() and category() to query those raw values, but that is rarely what you want. In fact it's an anti-pattern, as it's very common to lose the category information in the process or even misinterpret (by assuming the category to be the one you commonly expect).

Instead use the higher level accessor: message() (which gets a string description for the error_code using its actual category instance). This is perfect for logging - many libraries will even return localized strings.

Recent versions of boost add optional source_location() and a to_string() method.

Checking Error Conditions

As a rule you should never compare error_codes. Instead, use error_condition. The standard describes these:

  • error_code holds a platform-dependent error code
  • error_condition holds a portable error code

Though simplified, that's a good starting point.

Conditions allow one to handle conditions that may manifest with different error codes depending on platform, implementation and/or configuration.

An exception [sic] is when you write to a specific platform or implementation where you know a specific error_code is always expected.

E.g. in Asio you could have:

 asio::io_context io;
 asio::stead_timer timer(io, 3s);
 timer.async_wait([](error_code ec) {
      bool canceled = ec == asio::error::operation_aborted;
      std::cerr << (canceled?"canceled":"timed out") << "\n";
 });

This checks a specific error_code instance.

Note that even though error::operation_aborted is an enum value, the comparison takes the category into account because the conversion constructor invokes the make_error_code customization point which automatically adds the correct category.

The analogous implicit "factory" make_error_condition applies to error condition enums (typically called XXXXX_errc)

However, on other occasions you would prefer to check an error condition.

The best current write-up I know about error codes and conditions is by Peter Dimov in the Boost System Introduction: https://www.boost.org/doc/libs/1_80_0/libs/system/doc/html/system.html#usage_testing_for_specific_error_conditions