SaturnFramework / Saturn

Opinionated, web development framework for F# which implements the server-side, functional MVC pattern
https://saturnframework.org
MIT License
715 stars 109 forks source link

Preserve stack trace by default in controller (#280) #287

Closed retendo closed 3 years ago

retendo commented 3 years ago

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

NinoFloris commented 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)

retendo commented 3 years ago

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?

NinoFloris commented 3 years ago

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 :)

retendo commented 3 years ago

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?

NinoFloris commented 3 years ago

Exactly! See https://github.com/dotnet/fsharp/issues/8529

Krzysztof-Cieslak commented 3 years ago

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

Krzysztof-Cieslak commented 3 years ago

Published in 0.15.0-preview03