On Wednesday, 22 February 2012 at 07:30:54 UTC, H. S. Teoh wrote:
I have an idea. What if handlers took *two* arguments, a Condition, and a (possibly derived) Exception object? The raise system would then match conditions to handlers by both the Condition type and derived Exception
type.
*snip*


The Condition approach you propose is fairly similar to what I was thinking of, as an approach to fixing Problems that occur (not necessarily exceptions). One of the fundamental problems I have with exceptions is that, despite intended to be recoverable as opposed to Errors, they are not recoverable. The operation still fails when an exception is thrown, and you have to restart all over again (even if it's something easily recoverable from). The other issue, is that exceptions are just poorly designed for multithreaded and event based applications. If you queue some work to be done, you likely won't even know if an exception is thrown. If you have a callback / event based approach, you have to do the equivalent of returning error codes (something exceptions were designed to avoid), except with passing in error codes instead. An example is .NET forcing all asynchronous operations to have a Begin____ and an End____ with the End____ rethrowing whatever problems occurred during the operation (even if they were easily solveable if the caller simply had immediate access to handle them).

The first one, is solveable with something similar to Conditions. A Problem would generally be a state issue. For example, you're writing a simple file transfer tool. The client authenticates with the server and gets a session ID. The server then starts transferring to the client, when suddenly the client loses connection for a moment (maybe they lost Wi-Fi signal, maybe someone unplugged their router momentarily, maybe they just had a bad route). With the exception based approach, the only way to notify this is to stop the entire operation, reconnect, reauthenticate, create a new session, negotiate what was being transfered, negotiate how far in the transfer completed, and other annoying things. Instead, we could register a handler to solve network problems. At the lowest level, the socket could have a handler that attempts to reconnect if any socket operations fail due to a connection error. Then, the transfer protocol could have a handler that, if the dependent socket reconnect handler is successful, notifies the server of the session key (and maybe the last packet it received) and carries on seamlessly without having to do a bunch of work. If the socket reconnect fails, the network problem handler reports a failure, and the transfer protocol handler does not get executed. If there is no transfer protocol handler, or there is one that basically says a solution is not possible, the same happens. Instead, that Problem is executed into an Exception, as the operation could not continue. (Unfortunately, unless you have a global problem handler for the entire transfer operation, this still suffers from the second issue about how those exceptions do not get carried up to the caller that starte the operation.)

The transfer approach might not be the greatest example, but it demonstrates something that (IMO) Exceptions are misused for, which affects the design of Exceptions themselves as it attempts to hammer a solution they're not great for in with them.

Reply via email to