-
Notifications
You must be signed in to change notification settings - Fork 374
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
Support annotated-exception
#1762
base: master
Are you sure you want to change the base?
Support annotated-exception
#1762
Conversation
I've made a PR to add |
@@ -116,7 +117,7 @@ basicRunHandler rhe handler yreq resState = do | |||
return (HCContent defaultStatus tc)) | |||
(\e -> | |||
case fromException e of | |||
Just e' -> return e' | |||
Just (AnnotatedException _ e') -> return e' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This deserves a bit of commentary.
The instance Exception e => Exception (AnnotatedException e)
has a slightly magical terrible horrifying unusual implementation of fromException
.
The tests for this demonstrate the pattern, but tl;dr, the Exception
instance here on AnnotatedException
will work to catch both an AnnotatedException HandlerContents
and a HandlerContents
, which is then promoted to AnnotatedException mempty (hc :: HandlerContents)
.
Hi Matt, |
I'm happy to let this sit until folks feel good integrating it. At the very least, the issue and PR presence is useful for folks that inevitably run into trouble when using |
I’m OK with the change if you find this useful. But there are merge conflicts now, sorry for the delayed review |
@parsonsmatt do you need help finishing this? I'm interested |
I need to verify that the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a Yesod middleware at work that handles this unwrapping, and as long as it's the last middleware, everything works fine.
I want to write some tests and verify that this is properly integrated before recommending merging.
@@ -116,7 +117,7 @@ basicRunHandler rhe handler yreq resState = do | |||
return (HCContent defaultStatus tc)) | |||
(\e -> | |||
case fromException e of | |||
Just e' -> return e' | |||
Just (AnnotatedException _ e') -> return e' | |||
Nothing -> HCError <$> toErrorHandler e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, digging into this some more:
-- | Convert a synchronous exception into an ErrorResponse
toErrorHandler :: SomeException -> IO ErrorResponse
toErrorHandler e0 = handleAny errFromShow $
case fromException e0 of
Just (HCError x) -> evaluate $!! x
_ -> errFromShow e0
So I think this function needs to also check for AnnotatedException
- since the fromException e0 :: Maybe HCContents
won't work if the underlying application code is calling throwWithCallStack
.
-- | Generate an @ErrorResponse@ based on the shown version of the exception
errFromShow :: SomeException -> IO ErrorResponse
errFromShow x = do
text <- evaluate (T.pack $ show x) `catchAny` \_ ->
return (T.pack "Yesod.Core.Internal.Run.errFromShow: show of an exception threw an exception")
return $ InternalError text
Fortunately this should work fine - perhaps we want to unwrap the AnnotatedException
before showing it?
Fixes #1761
Before submitting your PR, check that you've:
@since
declarations to the Haddocks for new, public APIsAfter submitting your PR: