I use Async.Catch to handle exceptions thrown by asynchronous workflows:
work |> Async.Catch |> Async.RunSynchronously |> fun x -> match x with | Choice1Of2 _ -> () // success | Choice2Of2 ex -> // failure, handle exception
Today I noticed that OperationCanceledExceptions are not handled by Async.Catch. Instead of picking from Async.Catch, the exception continues to be thrown until it hits me. I expected the following test to be red, but it is green:
[<Test>] let ``Async.Catch doesnt work on OperationCancelledExceptions``() = use cancellationTokenSource = new System.Threading.CancellationTokenSource(1000) let work = async { while true do do! Async.Sleep 100 } (fun () -> work |> Async.Catch |> fun x -> Async.RunSynchronously (x, cancellationToken=cancellationTokenSource.Token) |> ignore) |> should throw typeof<System.OperationCanceledException>
Evaluating some exceptions using Async.Catch + Choices + matching, and some others using try / catch blocks do not look like this ... it will look like this, which is too complicated. Also, I am wondering what to use Async.Catch, since I should still use the try / catch block ...:
[<Test>] let ``evaluating exceptions of async workflows``() = use cancellationTokenSource = new System.Threading.CancellationTokenSource(1000) let work = async { while true do do! Async.Sleep 100 } try work |> Async.Catch |> fun x -> Async.RunSynchronously (x, cancellationToken=cancellationTokenSource.Token) |> fun x -> match x with | Choice1Of2 result -> ()
What is the best way to handle async workflow exceptions? Should I just reset Async.Catch and use try / catch blocks everywhere?
exception-handling f # async-workflow
stmax
source share