[Haskell-cafe] ANN: asynchronous-exceptions

Roman Cheplyaka roma at ro-che.info
Wed Feb 5 21:23:08 UTC 2014

Ok, this clears things up. I misinterpreted your approach thinking that
you're also solving the problem of distinguishing async vs sync
exceptions, only based on how they were thrown instead of their type.

I now see that it isn't the case — you're catching *all* exceptions.
(And run the timeout handler in a different thread.)

So no wonder that asynchronous-exceptions (whose description says that
it lets differentiate between sync and async exceptions, in a certain
sense) doesn't help you — you simply don't want any exceptions at all.

My use case is simpler — I write testing libraries. If a test throws an
exception, we have to decide whether we want to report it as a test's
failure or it's a bigger problem and we want to wrap up. 

I don't think there's a universally right way to make this decision. It
depends on what exceptions exist and what threads they can be thrown to.
E.g. if there existed something like UserInterrupt but which could be
thrown to any active thread, not only the main thread, then the approach
"run in a separate thread and log any exceptions from that thread"
simply wouldn't work.

For tasty, based on the async exceptions I'm aware of, I think your
approach is overall better. It's almost as simple, doesn't require
patching 3rd-party timeout libraries, and catches StackOverflow (which
is desirable). So I'll switch to it instead.

For smallcheck, the overhead of forkIO might be significant, because it
has to be performed for every single property check, and those can be
numerous and very quick. I put together a simple benchmark
(http://lpaste.net/99532 if anyone is interested) which shows that
overhead can be noticable (16% for async vs 4% for simple catch) but
tolerable, and it will be even less for more realistic properties.
So I'll probably use the async approach there, too, although I may
reconsider that in the future if I ever get to optimizing smallcheck and
squeezing out those percents.

As for the package itself, let's see if others will find any good use
cases for it. I'll update the docs with some conclusions from this

And thanks for your input.


* Michael Snoyman <michael at snoyman.com> [2014-02-05 18:48:22+0200]
> I can't think of any situation in which the semantics you're implying make
> sense. To me, catching synchronous exception is a simple concept: if an
> exception is generated internally to `userAction`, then it's a synchronous
> exception. If it was terminated by something external, then it's
> asynchronous. I'm not sure what you're getting at about my approach
> requiring knowledge of what's going on deep inside a library.
> The real question which is not explained in your package is what use case
> you're actually trying to address. Here's a prime example I've run into:
> you're writing a web application which uses a third-party library. If that
> library throws an exception of any type, you want to catch the exception
> and display an appropriate error message (or perhaps return some data from
> another source). However, we still want the web application to respect
> timeout messages from the server to avoid slowloris attacks. The handler
> code would look like:
> myHandler = do
>     eres <- tryAnyDeep someLibraryFunction
>     case eres of
>         Left e -> tellUser "I'm sorry, there was an issue making the query"
>         Right x -> displayData x
> The goal is that, under no circumstances, should someLibraryFunction be
> able to case the exception to escape tryAnyDeep. This includes rethrowing
> some async exception that it received from, e.g., a timeout. This would not
> be honored by trySync.
> Michael
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20140205/12e11122/attachment.sig>

More information about the Haskell-Cafe mailing list