It seems that the functionality of the Actor::errored() callback could be equivalently achieved internally by each actor - by wrapping its real handle() in an error-handling shim handle(). System::run_actor_select_loop() could then unconditionally abort the loop when error occurs.
The only functional difference I could find was that metrics are not currently collected when Actor::handle() returns error and Actor::errored() returns Recoverable. But I'm not sure whether that's intentional.
In order not to regress in ergonomics, the crate (or users themselves) can provide wrapper (or adapter) actors that would provide the boilerplate. Imagine struct LogAndIgnoreErrorsAdapter<A: Actor>(inner: A); impl Actor for LogAndIgnoreErrorsAdapter {...} or something along that lines. A drop-in replacement adapter with errored() is also possible.
In other words: we might replace one method on the central trait by composing the existing concepts instead.
It seems that the functionality of the
Actor::errored()
callback could be equivalently achieved internally by each actor - by wrapping its realhandle()
in an error-handling shimhandle()
.System::run_actor_select_loop()
could then unconditionally abort the loop when error occurs.The only functional difference I could find was that metrics are not currently collected when
Actor::handle()
returns error and Actor::errored() returnsRecoverable
. But I'm not sure whether that's intentional.In order not to regress in ergonomics, the crate (or users themselves) can provide wrapper (or adapter) actors that would provide the boilerplate. Imagine
struct LogAndIgnoreErrorsAdapter<A: Actor>(inner: A); impl Actor for LogAndIgnoreErrorsAdapter {...}
or something along that lines. A drop-in replacement adapter witherrored()
is also possible.In other words: we might replace one method on the central trait by composing the existing concepts instead.