Closed retendo closed 3 years ago
Thanks for the contribution!
A bit better, as opposed to reflection of exception internals, would be to use ExceptionDispatchInfo.Capture(ex).Throw()
(System.Runtime.ExceptionServices)
This is the supported api to do what you want (and it's used in the F# compiler, F# core, and clr core libraries)
With ExceptionDispatchInfo.Capture(ex).Throw()
there would just be a lot of added lines like
--- End of stack trace from previous location where exception was thrown ---
.
I don't mind that, should I change it?
Looking at the problem from a slightly different angle, it might be better to change the internal controller state to take an ErrorHandler option
. In controllerWithErrorHandler guard on it being Some in the try ... with ex when state.ErrorHandler.IsSome -> state.ErrorHandler.Value ex
and the compiler will then emit the EDI call :)
Without a fallback like this?
let controllerWithErrorHandler nxt ctx : HttpFuncResult =
task {
try
return! initialController nxt ctx
with
| ex when state.ErrorHandler.IsSome -> return! state.ErrorHandler.Value ctx ex
}
That would lead the exception to fall through to the router/application level, so no need for the explicit EDI call?
Exactly! See https://github.com/dotnet/fsharp/issues/8529
The same thing should be done for the Endpoint-Routing version of Controllers in https://github.com/SaturnFramework/Saturn/blob/master/src/Saturn/ControllerEndpoint.fs
Published in 0.15.0-preview03
This should preserve the stack trace when exceptions are thrown while using controllers that have no dedicated error handler.
This solves a part of #280