-
Notifications
You must be signed in to change notification settings - Fork 833
Description
When a non-Exception object is thrown (from CIL or other languages that support it), it cannot be caught in F# by default.
Repro steps
let throwobj (x:obj) = (# "throw" x #) // or any other code that throws a non-Exception instance
try
throwobj "test"
with
| e -> printf "%O" eExpected behavior
The exception should be caught either as System.String or System.Runtime.CompilerServices.RuntimeWrappedException.
Actual behavior
Unhandled exception. System.InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Exception'.
This is caused by the generated exception handler:
.try
{
ldstr "test"
throw
// ...
}
catch [netstandard]System.Object
{
castclass [System.Runtime]System.Exception // InvalidCastException
stloc.0
// ...
}F# here catches everything, but the cast to Exception throws another exception since the object is not an Exception.
Known workarounds
The code above succeeds if the attribute that controls how wrapped exceptions are exposed is used explicitly:
[<assembly: System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows = true)>]do()Related information
Throwing a RuntimeWrappedException manually does not exhibit this behaviour because the runtime does not treat it as a special case then and does not unwrap the value.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status