diff --git a/src/Compiler/Driver/GraphChecking/GraphProcessing.fs b/src/Compiler/Driver/GraphChecking/GraphProcessing.fs index 332ed2a00ec..2cadaf25ac5 100644 --- a/src/Compiler/Driver/GraphChecking/GraphProcessing.fs +++ b/src/Compiler/Driver/GraphChecking/GraphProcessing.fs @@ -91,9 +91,10 @@ let processGraph<'Item, 'Result when 'Item: equality and 'Item: comparison> /// Only the first exception encountered is stored - this can cause non-deterministic errors if more than one item fails. let raiseExn, getExn = let mutable exn: ('Item * System.Exception) option = None + let lockObj = obj () // Only set the exception if it hasn't been set already let setExn newExn = - lock exn (fun () -> + lock lockObj (fun () -> match exn with | Some _ -> () | None -> exn <- newExn diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 0145bcfa609..c99458dabbf 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -207,6 +207,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/GraphProcessingTests.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/GraphProcessingTests.fs new file mode 100644 index 00000000000..3e5483b0a7f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/Graph/GraphProcessingTests.fs @@ -0,0 +1,23 @@ +module TypeChecks.GraphProcessingTests + +open System.Threading +open FSharp.Compiler.GraphChecking.GraphProcessing +open NUnit.Framework + +[] +let ``When processing a node throws an exception, an exception is raised with the original exception included`` () = + let graph = [1, [|2|]; 2, [||]] |> readOnlyDict + let work (_processor : int -> ProcessedNode) (_node : NodeInfo) : string = failwith "Work exception" + + let exn = + Assert.Throws( + fun () -> + processGraph + graph + work + CancellationToken.None + |> ignore + ) + Assert.That(exn.Message, Is.EqualTo("Encountered exception when processing item '2'")) + Assert.That(exn.InnerException, Is.Not.Null) + Assert.That(exn.InnerException.Message, Is.EqualTo("Work exception"))