Note. It is better to read [so-5.5 Basics] before this text.
This example shows how an agent can specify what SObjectizer should do in the case when agent's event handler throws an exception.
There is a very simple rule: an agent must not throws an exception from an event handler. It is because SObjectizer doesn't known is agent support exception safety or not. Sometimes agent can continue its work after exception, but sometimes it is in invalid state and work cannot be continued.
Because of that the default reaction to an exception from an event handler is application termination. In the most cases this is an appropriate policy because in the modern C++ it is hard to predict the moment and the reason of exception. For example, an attempt to add a item to a vector or to concatenate two strings could lead to an exception (std::bad_alloc
). And in the most cases unexpected exception means that application cannot continue its work.
But sometimes agents can do stateless operations (like conversion from one units to others) and exceptions do not damage agent states. Instead of catching all the exceptions agent can specify what SObjectizer should do in the case of an exception.
This could be done by redefining virtual method so_5::agent_t::so_exception_reaction()
. Agent must return the appropriate value of so_5::exception_reaction_t
enumeration.
SObjectizer calls this method in the case of unhandled exception. SObjectizer calls this method and then do the appropriate action like application termination (by calling std::abort()
), normal SObjectizer Environment shutdown, cooperation deregistration or ignorance of the exception caught.
One agent is created in the sample. It throws an exception in so_evt_start()
method. This exception is caught by SObjectizer. Then SObjectizer calls so_exception_reaction()
method and do the required action: shut down the SObjectizer Environment normally.
/* * A sample for the exception reaction. */ #include <iostream> #include <stdexcept> // Main SObjectizer header file. #include <so_5/all.hpp> // A class of an agent which will throw an exception. class a_hello_t : public so_5::agent_t { public: a_hello_t( context_t ctx ) : so_5::agent_t( ctx ) {} virtual ~a_hello_t() {} virtual void so_evt_start() override { throw std::runtime_error( "sample exception" ); } virtual so_5::exception_reaction_t so_exception_reaction() const override { return so_5::shutdown_sobjectizer_on_exception; } }; int main() { try { so_5::launch( []( so_5::environment_t & env ) { env.register_agent_as_coop( "coop", env.make_agent< a_hello_t >() ); } ); } catch( const std::exception & ex ) { std::cerr << "Error: " << ex.what() << std::endl; return 1; } return 0; }
Please see [so-5.2.3 Reaction to unhandled exceptions] and [so-5.3.0 Exception reaction inheritance] for the better understanding of the SObjectizer's exception handling mechanism.
Wiki: Basics
Wiki: so-5.2.3 Reaction to unhandled exceptions
Wiki: so-5.3.0 Exception reaction inheritance
Wiki: so-5.5 Basics