Comment on page
Exception Converter Suite
An
ExceptionConverterSuite
allows multiple Exception Converters to be grouped together, so that when a task is executed and an exception is thrown, it can be converted into the appropriate Failure object.If an
Exception
does not have an ideal ExceptionConverter
, then it will be converted to the base Failure
object using the FallbackExceptionConverter.This class exposes three methods:
Method | Description |
---|---|
observe | Executes an asynchronous task and returns a Failure when an Exception is thrown. |
observeSync | Executes a synchronous task and returns a Failure when an Exception is thrown. |
convert | Directly converts a passed Exception into a Failure object. |
Using the
observe
or observeSync
method of the ExceptionConverterSuite
, we can run a task that returns an Either monad containing a Left
(failed) or Right
(success) value. If any exception occurs while running the task, then a Left
object will be returned containing the respective Failure
object of the exception.There are various approaches to converting an
Exception
into a Failure
object, each with its own advantages:Default exception converters can be configured when instantiating a
ExceptionConverterSuite
object:This is suitable if we want a group of exception converters to take effect on any
observe
, observeSync
and convert
method calls of the class.// Create an exception converter suite that converts a `SocketException`
// into a `NetworkFailure`
final exceptionConverterSuite = ExceptionConverterSuite(
exceptionConverters: [SocketExceptionConverter.new],
);
final result = await exceptionConverterSuite.observe<void>(
task: (messageLog) async {
// Some code to execute
...
// Simulate exception
throw const SocketException('test');
},
);
// A `Left` object containing a `NetworkFailure`
print('result: $result');
Exceptions converters can also be passed to the
observe
, observeSync
and convert
methods when calling them:This is ideal if we want to use a custom exception converter to be used for a particular method call, taking precedence over the default exception converters.
final exceptionConverterSuite = ExceptionConverterSuite();
final result = exceptionConverterSuite.observeSync<void>(
// Provide an exception converter as an argument
exceptionConverters: [const SocketExceptionConverter()],
task: (messageLog) {
// Some code to execute
...
// Simulate exception
throw const SocketException('test');
},
);
// A `Left` object containing a `NetworkFailure`
print('result: $result');
In some cases, creating a custom exception converter may be unnecessary, particularly if an exception only occurs in a specific location. In these situations, you can manually convert an exception into a failure instead:
This is ideal if we want to manually handle a specific exception.
final exceptionConverterSuite = ExceptionConverterSuite();
final result = exceptionConverterSuite.observeSync<void>(
task: (messageLog) {
try {
// Simulate exception
throw const SocketException('test');
} on SocketException {
return const Left(NetworkFailure());
}
},
);
// A `Left` object containing a `NetworkFailure`
print('Convert result: $result');
A task can automatically be logged by providing a
MessageLog
(from the Codenic Logger) to the observe
and observeSync
method calls. This allows you to construct log messages by passing it data and assigning a message which will automatically be displayed at the end of the task's execution.Automatic logging is done when any of the following events occur:
When a
Left
value is returned, then a logger.warn
will be called to print the messageLog
:exceptionConverterSuite.observeSync<void>(
messageLog: MessageLog(id: 'test-message-log'),
task: (messageLog) {
messageLog?.data.addAll({'lorep': 2});
messageLog?.message = 'Test warning message';
return const Left(NetworkFailure());
},
);

When a
Right
value is returned, then a logger.info
will be called to print the messageLog
:exceptionConverterSuite.observeSync<void>(
messageLog: MessageLog(id: 'test-message-log'),
task: (messageLog) {
messageLog?.data.addAll({'lorep': 2});
messageLog?.message = 'Test info message';
return const Right(null);
},
);
.webp?alt=media&token=0048d588-d2e4-4c5f-bb48-4a05f4848495)
When an exception is thrown, an
ExceptionConverter
can catch that exception and decide whether to print the logs.Using our SocketExceptionConverter example, this calls
logger.wtf
to print the messageLog
when a SocketException
is thrown:exceptionConverterSuite.observeSync<void>(
exceptionConverters: const [SocketExceptionConverter()],
messageLog: MessageLog(id: 'test-message-log'),
task: (messageLog) {
messageLog?.data.addAll({'lorep': 2});
messageLog?.message = 'Test exception converter message';
throw SocketException('test');
},
);

Last modified 11mo ago