I would like to be able to return custom error pages and statuses to the user, and end computation in the ActionT monad when such an error occurs. My understanding is that this is a bit like a Maybe
monad, where computation ends when the first Nothing
is encountered, but with a final error message emitted (to the user via HTTP).
I have a code snippet that looks like this:
liftIO $ scotty (config & port & fromEnum) $
get "/cow/:mark" $ do
qParams :: DM.Map LTxt.Text LTxt.Text <- DM.fromList <$> params
markTxt <- param "mark"
let intervalTxtMay = DM.lookup "interval" qParams
let cowMarkMaybe = TR.readMaybe $ Txt.unpack markTxt
cowMark <- case cowMarkMaybe of
Nothing -> do
status status404
textLazy $ "Couldn't parse cow mark " ++ markTxt ++ " as integer."
finish
Just cmVal-> pure $ CowMark cmVal
liftIO $ logLogIt Debug lgr ["***** Made it past cowMark ******"]
...
There are at least two problems with the code: finish
doesn't seem to do anything particularly useful here, i.e., computation continues and I still see the message ***** Made it past cowMark ******
in my logs each time load a page that would normally trigger the 404.
The second problem is that the 404 error is not enacted, I get a 200 response even when it should be a 404.
Is there a way to achieve the desired behavior in Scotty?
Both problems stem from the Nothing
case never being entered, because the TR.readMaybe
always succeeds. Print markTxt
and cowMarkMaybe
in a case where the latter should be Nothing
.