The Safe effect is useful to handle resources which must be closed even in the presence of exceptions. The main operations are
finally
to create an action which must always be
executed after another one, even if the first one failscatchThrowable
to handle a thrown exceptionbracket(open)(step)(close)
to open a resource, use it
and then close it safely. The close
part is a “finalizer”
Let’s see an example for the protection of a resource: ``
> Results
Without exception: Right(55), finalizers exceptions: no exceptions, resource is closed: true
With exception : Left(boo), finalizers exceptions: no exceptions, resource is closed: true
As you can see in the signature of program
the return
value of runSafe
is
(Throwable Either A, List[Throwable])
. The first part is
the result of your program, which may end with an exception, and the
second part is the list of possible exceptions thrown by the finalizers
which can themselves fail.
A simpler version of bracket
is
finally
.
This example show how to use finally
but also what
happens if a finalizer fails:``
> Results
Computation ok, finalizer ok: Right(55), finalizers exceptions: no exceptions
Computation ok, finalizer ko: Right(55), finalizers exceptions: List(failed!!)
Computation ko, finalizer ok: Left(boo), finalizers exceptions: no exceptions
Computation ko, finalizer ko: Left(boo), finalizers exceptions: List(failed!!)
Finally (no pun intended!) note that you can use
execSafe
if you are not interested in the result of the
finalizers.