Skip to content

SO 5.8 ByExample Exception Reaction

Yauheni Akhotnikau edited this page Jul 7, 2023 · 1 revision

Note. It is better to read SO-5.8 Basics before this text.

Introduction

This example shows how an agent can specify what SObjectizer should do in the case when agent's event handler throws an exception.

Some Words About Exceptions from an Agent's Event Handler

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.

What Sample Does

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.

Sample Code

#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 final : public so_5::agent_t
{
	public:
		a_hello_t( context_t ctx ) : so_5::agent_t( ctx )
		{}

		void so_evt_start() override
		{
			throw std::runtime_error( "sample exception" );
		}

		so_5::exception_reaction_t so_exception_reaction() const noexcept override
		{
			return so_5::shutdown_sobjectizer_on_exception;
		}
};

int main()
{
	try
	{
		so_5::launch( []( so_5::environment_t & env ) {
				env.register_agent_as_coop( env.make_agent< a_hello_t >() );
			} );

	}
	catch( const std::exception & ex )
	{
		std::cerr << "Error: " << ex.what() << std::endl;
		return 1;
	}

	return 0;
}

See Also

Please see SO-5.8 InDepth Exceptions for the better understanding of the SObjectizer's exception handling mechanism.

Clone this wiki locally