From a987fed8337c03390958e37e451c321cbb66c40c Mon Sep 17 00:00:00 2001 From: njlr Date: Fri, 26 Sep 2025 17:31:11 +0100 Subject: [PATCH] Adds getOrReraise and tests --- src/FsToolkit.ErrorHandling/AsyncResult.fs | 17 ++++++++++ .../AsyncResult.fs | 32 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/FsToolkit.ErrorHandling/AsyncResult.fs b/src/FsToolkit.ErrorHandling/AsyncResult.fs index 5b0d5d95..b4633422 100644 --- a/src/FsToolkit.ErrorHandling/AsyncResult.fs +++ b/src/FsToolkit.ErrorHandling/AsyncResult.fs @@ -1,6 +1,9 @@ namespace FsToolkit.ErrorHandling open System.Threading.Tasks +#if !FABLE_COMPILER +open System.Runtime.ExceptionServices +#endif [] module AsyncResult = @@ -342,6 +345,20 @@ module AsyncResult = | Choice2Of2 ex -> Error(exnMapper ex) ) + /// Gets the value in the Ok case or re-raises the exception in the Error case + let inline getOrReraise (input: Async>) : Async<'ok> = + async { + match! input with + | Ok a -> return a + | Error exn -> +#if FABLE_COMPILER + return raise exn +#else + ExceptionDispatchInfo.Capture(exn).Throw() + return Unchecked.defaultof<_> +#endif + } + /// Lift Async to AsyncResult let inline ofAsync (value: Async<'ok>) : Async> = value diff --git a/tests/FsToolkit.ErrorHandling.Tests/AsyncResult.fs b/tests/FsToolkit.ErrorHandling.Tests/AsyncResult.fs index 6f07c095..77cec8d4 100644 --- a/tests/FsToolkit.ErrorHandling.Tests/AsyncResult.fs +++ b/tests/FsToolkit.ErrorHandling.Tests/AsyncResult.fs @@ -714,6 +714,37 @@ let catchTests = <| Expect.hasAsyncErrorValue "unmapped" (AsyncResult.catch f (toAsync (Error "unmapped"))) ] +let getOrReraiseTests = + let makeException () : exn = + try + failwith "Kaboom" + with exn -> + exn + + testList "AsyncResult.getOrReraise tests" [ + testCaseAsync "getOrReraise preserves message and stack-trace" + <| async { + let exn = makeException () + + let! captured = + async { + try + let! () = + AsyncResult.error exn + |> AsyncResult.getOrReraise + + return failwith "Unexpected" + with exn -> + return exn + } + + Expect.equal captured.Message exn.Message "" +#if !FABLE_COMPILER + Expect.equal captured.StackTrace exn.StackTrace "" +#endif + } + ] + type CreatePostResult = | PostSuccess of NotifyNewPostRequest | NotAllowedToPost @@ -1023,6 +1054,7 @@ let allTests = teeErrorTests teeErrorIfTests catchTests + getOrReraiseTests asyncResultCETests asyncResultOperatorTests zipTests