Skip to content
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

309 handle application exceptions with 500 errors #954

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

v0d1ch
Copy link

@v0d1ch v0d1ch commented Apr 26, 2018

fixes #309

Sasa Bogicevic added 3 commits April 26, 2018 14:24
add deepseq dep
Hardcode bool param for now
@qrilka
Copy link

qrilka commented Apr 27, 2018

@v0d1ch I've tried out a90b671 and it doesn't seem to work properly, See https://gist.github.com/qrilka/49b0634fce17bcbd2cd4abea503a0f8c

@qrilka
Copy link

qrilka commented Apr 27, 2018

Update doesn't seem to change the result.
BTW maybe it's worth to fix issue with boolean blindness here?
Using serveWithContext and opaque (True :. EmptyContext) doesn't look quite user-friendly API

@v0d1ch
Copy link
Author

v0d1ch commented Apr 27, 2018

Yeah I could probably use some help here.

Copy link
Contributor

@phadej phadej left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test case would be also nice. (Something which was broken before, but isn't broken with the patch)

-> RouteResult Response -> IO ResponseReceived
maybeEval resp =
if fullyEvaluate
then force resp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


serveWithContext :: (HasServer api context)
serve :: (HasServer api '[Bool]) => Proxy api -> Server api -> Application
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm against of using Context to guide whether to eval or not eval. IMHO single global choice should be enough for now.

Something #309 (comment) is good.

Context won't work for subapis anyway, as we give only single Context to serveWithContext. And if we use combinators to alter the context, we could be more direct and alter "whether to eval or not".

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment suggests both a global setting & a Context. Are you requesting both, or just the global?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just global I think.

@v0d1ch v0d1ch force-pushed the 309-handle-application-exceptions-with-500-errors branch from 93434e4 to 5b13ff4 Compare July 5, 2018 22:30
routingRespond (Fail err) = respond $ responseServantErr err
routingRespond (FailFatal err) = respond $ responseServantErr err
routingRespond (Route v) = respond v
toApplication :: Bool -> RoutingApplication -> Application
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last nitpick: let's have

data Evaluate = Force | Lazy deriving (Show)

so we won't be Bool-blind.

@@ -46,3 +46,10 @@ instance MonadBaseControl IO Handler where

runHandler :: Handler a -> IO (Either ServantErr a)
runHandler = runExceptT . runHandler'

-- determins if response should be reduced to NF
data Evaluate =
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phadej Is this a good place for this type ?

@@ -132,7 +132,7 @@ serve p = serveWithContext p EmptyContext
serveWithContext :: (HasServer api context)
=> Proxy api -> Context context -> Server api -> Application
serveWithContext p context server =
toApplication (runRouter (route p context (emptyDelayed (Route server))))
toApplication Force (runRouter (route p context (emptyDelayed (Route server))))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@phadej Should I alter serveWithContext to take in another param that will determine if we want to NF the response or not ? How would you like this to look for the end user in a sense do you want them to be able to control the response evaluation ?

Comment on lines +104 to +107
maybeEval resp =
case fullyEvaluate of
Force -> force resp
Lazy -> resp
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still trying to figure out what's going on here, but this looks slightly more correct to me:

Suggested change
maybeEval resp =
case fullyEvaluate of
Force -> force resp
Lazy -> resp
maybeEval cont =
case fullyEvaluate of
Force -> \resp -> resp `deepseq` cont resp
Lazy -> cont

@tchoutri
Copy link
Contributor

Hi @v0d1ch! Could you please rebase your PR? :)
If you are willing to finish the work on this, it can be feature in the next major release of Servant!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle application exceptions with 500 errors
7 participants