-
-
Notifications
You must be signed in to change notification settings - Fork 412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Catch ServantErr exceptions in liftIO definition for Handler? #1111
Comments
Use application specific monad; not Handler. Then you have freedom to make whatever you want regarding exceptions.
My priority is to drive #841 home, so we could remove ExceptT out of Handler. As that removal is a goal of design, catching ServantErr doesn't make sense long-term.
Use application specific monad and `hoistServer`.
… On 3 Feb 2019, at 15.01, David Baynard ***@***.***> wrote:
Would it be possible to change the MonadIO instance for Handler to the following (lawful) instance?
instance MonadIO Handler where
liftIO :: IO a -> Handler a
liftIO = Handler . ExceptT . tryJust (fromException @ServantErr)
The original is here:
https://github.com/haskell-servant/servant/blob/109f7b2a45ffe86dd707b89bf5fd51d440381b05/servant-server/src/Servant/Server/Internal/Handler.hs#L28-L33
This ensures that all ServantErr exceptions are handled.
As far as I can tell, there are two basic ways to throw a ServantErr.
An example (with output)
throwError :: ServantErr -> Handler a
throwM :: ServantErr -> Handler a
The former is considered an application error, and will be processed by servant. The latter will not, and will be processed by the server (in this case, warp). I can't see any circumstances in which anybody may wish to throw a server error (throwM), as opposed to an application error (throwError). Briefly,
λ> runHandler (throwError err400)
Left (ServantErr {errHTTPCode = 400, errReasonPhrase = "Bad Request", errBody = "", errHeaders = []})
λ> runHandler (throwM err400)
*** Exception: ServantErr {errHTTPCode = 400, errReasonPhrase = "Bad Request", errBody = "", errHeaders = []}
In using a custom handler, I've encountered an issue resulting from this, which I've realised might be best fixed by changing the MonadIO instance for Handler.
If there's no reason to throw a server error, then would it not be better to define the instance so that any ServantErr is processed as an application error instead?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Would it be possible to change the
MonadIO
instance forHandler
to the following (lawful) instance?The original is here:
servant/servant-server/src/Servant/Server/Internal/Handler.hs
Lines 28 to 33 in 109f7b2
This ensures that all
ServantErr
exceptions are handled.As far as I can tell, there are two basic ways to throw a
ServantErr
.An example (with output)
The former is considered an application error, and will be processed by servant. The latter will not, and will be processed by the server (in this case,
warp
). I can't see any circumstances in which anybody may wish to throw a server error (throwM
), as opposed to an application error (throwError
). Briefly,In using a custom handler, I've encountered an issue resulting from this, which I've realised might be best fixed by changing the
MonadIO
instance forHandler
.If there's no reason to throw a server error, then would it not be better to define the instance so that any
ServantErr
is processed as an application error instead?The text was updated successfully, but these errors were encountered: