I'm noticing that in many of the Boost ASIO examples, calls are being made to functions which can throw on error, but no try/catch is used. For example, the blocking UDP client example here has the following function:
void check_deadline()
{
// Check whether the deadline has passed. We compare the deadline against
// the current time since a new asynchronous operation may have moved the
// deadline before this actor had a chance to run.
if (deadline_.expires_at() <= deadline_timer::traits_type::now())
{
// The deadline has passed. The outstanding asynchronous operation needs
// to be cancelled so that the blocked receive() function will return.
//
// Please note that cancel() has portability issues on some versions of
// Microsoft Windows, and it may be necessary to use close() instead.
// Consult the documentation for cancel() for further information.
socket_.cancel();
// There is no longer an active deadline. The expiry is set to positive
// infinity so that the actor takes no action until a new deadline is set.
deadline_.expires_at(boost::posix_time::pos_infin);
}
// Put the actor back to sleep.
deadline_.async_wait(boost::bind(&client::check_deadline, this));
}
The documention for deadline_.expires_at (here) states that this function throws a boost::system::system_error exception.
Is this not caught in this example because it is simply an example, or do exceptions thrown from calls like this propagate up through a call to run, run-one, etc? In other words, is it sufficient to wrap the call to io_service.run() with a try catch to handle these types of exceptions?
Further, I also noticed that the deadline_.async_wait documentation here states that the handler requires a signature with a reference to a boost::system::system_error::error_code. I'm not seeing a reference or a placeholder in the check_deadline() function.