scotty-web / scotty

Haskell web framework inspired by Ruby's Sinatra, using WAI and Warp (Official Repository)
http://hackage.haskell.org/package/scotty
BSD 3-Clause "New" or "Revised" License
1.72k stars 134 forks source link

How can I catch errors? #215

Closed chrissound closed 4 years ago

chrissound commented 6 years ago

https://github.com/chrissound/ScottyExceptionTest

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Web.Scotty
import Control.Monad.IO.Class
import Control.Exception

main :: IO ()
main = do
  catch (
    scotty 3000 $ do
      defaultHandler (\e -> do
                        liftIO $ print "error handler reached"
                        html e)
      get "/r" $ do
        raise "this gets caught"
      get "/e" $ do
        error "this does not"
   ) (\e -> do
        print ("An exception has been caught" :: String)
        putStrLn $ show (e :: SomeException)
    )

/e produces HTTP output of "Something went wrong" produces STDout output of

    this does not
  CallStack (from HasCallStack):
    error, called at /home/chris/Projects/Haskell/ScottyExceptionTest/src/Main.hs:18:9 in main:Main

/r produces HTTP output of "this gets caught" produces STDout output of "error handler reached"


It seems I can't catch the error for /e?

chrissound commented 6 years ago

It seems I need to surround the error "this does not" with liftAndCatchIO. I think the documentation for defaultHandler is slightly misleading in this case.

Akii commented 6 years ago

This works until you use scottyT. Then it becomes really awkward. I feel like scotty's types are missing some "modern" type classes? MonadThrow MonadCatch and the like.

elrikdante commented 6 years ago

Would liftAndCatchIO from here help?

https://hackage.haskell.org/package/scotty-0.11.0/docs/Web-Scotty-Trans.html#t:ScottyError

I use it when interleaving database connections.

Akii commented 6 years ago

No, I'd need something like liftAndCatch :: (ScottyError e, MonadIO m) => m a -> ActionT e m a. I'll investigate this now and see if I can come up with a solution either on Scotty side or on my side.

Akii commented 6 years ago

So apparently Scotty on master has all that stuff but on Hackage it's missing. Which makes me a sad panda.

RyanGlScott commented 6 years ago

@Akii, I'll try to prepare a new release this weekend.

Akii commented 6 years ago

Thank you very much! Let me know if I can help you, I'm on IRC as well.

RyanGlScott commented 6 years ago

I've uploaded scotty-0.11.1 to Hackage.

Akii commented 6 years ago

Thanks!

Another issue with the defaultHandler I just found: It must be the first handler in the ScottyM.

Adjusting the example code above to:

main = do
  catch (
    scotty 3000 $ do
      get "/r" $ do
        raise "this gets caught"
      get "/e" $ do
        error "this does not"
      defaultHandler (\e -> do
                        liftIO $ print "error handler reached"
                        html e)
   ) (\e -> do
        print ("An exception has been caught" :: String)
        putStrLn $ show (e :: SomeException)
    )

When calling:

curl -XGET localhost:3000/r
<h1>500 Internal Server Error</h1>this gets caught% 

Should be documented. I'll open a PR.

ad-si commented 5 years ago

@Akii Did you open a merge request? I just got bitten by this 🙈

Akii commented 5 years ago

Probably not, got discouraged after opening my first PR, I guess.. Seeing it's still open I feel reassured. :) I've no idea what this is even about anymore lol

ad-si commented 5 years ago

yeah, the project seems a little unmaintained 😕

chessai commented 4 years ago

this is resolved, remaining issue mentioned is on #237