SO 5.8 ByExample Custom Exception Logger - Stiffstream/sobjectizer GitHub Wiki
Note. It is better to read SO-5.8 Basics, SO-5.8 ByExample Exception Reaction, and SO-5.8 ByExample Custom Error Logger before this text.
This examples demonstrates usage of custom exception logger with SObjectizer Environment.
SObjectizer distunguishes errors and exceptions thrown from by event handlers. Errors are negative results of some actions performed by SObjectizer or inside SObjectizer RunTime (such as a problem with delivering a message or inability to start another worker thread). Information about errors is logged by using the error logger. See SO-5.8 ByExample Custom Error Logger as an example.
But an exception thrown from an event handler is a different story. The instance of that exception will be lost anyway (SObjectizer will either terminate the application or discard the exception). If a user wants to log the fact that an exception was thrown, he/she can set a custom event exception logger. SObjectizer will use this exception logger only when SObjectizer catches an exception from an event handler.
The sample implements so_5::event_exception_logger_t
interface. It installs an instance of that implementation as an event exception logger for SObjectizer Environment.
To provoke SObjectizer to use the exception logger agent of type a_hello_t
throws an exception from its so_evt_start
. This exception is intercepted by SObjectizer RunTime and is logged by using the user provided event exception logger. The agent a_hello_t
uses so_5::deregister_coop_on_exception
exception reaction and it tells the SObjectizer to deregister the coop with the agent that has thrown the exception.
/*
* A sample of the exception logger.
*/
#include <iostream>
#include <stdexcept>
// Main SObjectizer header file.
#include <so_5/all.hpp>
// A class of the exception logger.
class sample_event_exception_logger_t final
: public so_5::event_exception_logger_t
{
public:
// A reaction to an exception.
void log_exception(
const std::exception & event_exception,
const so_5::coop_handle_t & coop ) noexcept override
{
std::cerr
<< "Event_exception, coop:"
<< coop << "; "
" error: "
<< event_exception.what()
<< std::endl;
}
};
// 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 )
{}
// A reaction to start work in SObjectizer.
void so_evt_start() override
{
so_environment().install_exception_logger(
std::make_unique<sample_event_exception_logger_t>() );
throw std::runtime_error( "sample exception" );
}
// An instruction to SObjectizer for unhandled exception.
so_5::exception_reaction_t so_exception_reaction() const noexcept override
{
return so_5::deregister_coop_on_exception;
}
};
int main()
{
try
{
so_5::launch(
// SObjectizer initialization code.
[]( so_5::environment_t & env )
{
// Creating and registering cooperation with a single agent.
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;
}
Custom event exception logger is implemented as class custom_logger_t
in the sample code:
// A class of the exception logger.
class sample_event_exception_logger_t final
: public so_5::event_exception_logger_t
{
public:
// A reaction to an exception.
void log_exception(
const std::exception & event_exception,
const so_5::coop_handle_t & coop ) noexcept override
{
std::cerr
<< "Event_exception, coop:"
<< coop << "; "
" error: "
<< event_exception.what()
<< std::endl;
}
};
It is a very simple implementation. The base interface, so_5::event_exception_logger_t
has just one pure virtual method -- log_exception()
. This method must be reimplemented in descendant classes and sample_event_exception_logger_t
does just that.
The log_exception()
method has two parameters:
- event_exception. This is the instance that has been caught by SObjectizer RunTime;
- coop. This is the handle of the coop to that the problematic agent belongs.
The custom error logger is installed into SObjectizer Environment by a_hello_t
agent:
so_environment().install_exception_logger(
so_environment().install_exception_logger(
std::make_unique<sample_event_exception_logger_t>() );
An event exception logger object must be created as dynamically allocated object and must be passed to SObjectizer Environment as std::unique_ptr.
NOTE. A custom event exception logger can also be installed via so_5::environment_params_t
:
so_5::launch([](so_5::environment_t & env) {...},
[](so_5::environment_params_t & params) {
params.event_exception_logger(
std::make_unique<sample_event_exception_logger_t>());
});