如何从Handler中抛出异常

时间:2016-05-29 19:07:17

标签: haskell yesod

我正在构建一个RESTful端点,如果存在无效数据,应该抛出错误。这是一个简化(略显愚蠢)的版本:

getEventsR :: Handler Value
getEventsR = do
    mpage   <- lookupGetParam "page"
    let filters = case hasPage mpage of
                      Right val -> val
                      Left val  -> error $ T.unpack val -- Throw an error

     -- The rest...


hasPage :: Maybe Text -> Either Text Text
hasPage = 
    Left "This should error out"
  1. 这是正确的方法 - 函数应返回Either,稍后会扩展为错误吗?
  2. 我可能不应该使用error,对吧?又是什么?
  3. 作为旁注,如果我的抛出错误也会以JSON格式发送,我会很高兴。

    更新

    我使用术语“抛出异常”的原因是因为我的代码看起来像这样(简化):

    let selectOpt = case addPager [] of
                        Right val -> val
                        Left val  -> error $ T.unpack val
    
    let filters = case addFilter [] of
                        Right val -> val
                        Left val  -> error $ T.unpack val
    
    events <- runDB $ selectList filters selectOpt :: Handler [Entity Event]
    

    因此,如果它在selectOpt上出错,我希望它能够短路,而不是继续使用其余的处理程序。

1 个答案:

答案 0 :(得分:1)

您可以使用sendResponseStatus直接指定回复:

getEventsR = do
  mpage   <- lookupGetParam "page"
  case hasPage mpage of
    Left message -> sendResponseStatus status400 message
    Right val    -> ...continue processing with val...

sendResponseStatus的第二个参数可以是具有ToTypedContent实例的任何类型。其中包括TextValue和其他常见类型。有关默认定义此实例的类型,请参阅this page

<强>更新

回应你的意见......

get404定义为:

get404 key = do
    mres <- get key
    case mres of
        Nothing -> notFound'
        Just res -> return res

notFound' :: MonadIO m => m a
notFound' = liftIO $ throwIO $ HCError NotFound

HCErrorHandlerContents类型的构造函数:

http://hackage.haskell.org/package/yesod-core-1.4.0/docs/Yesod-Core-Types.html#t:HandlerContents

data HandlerContents:
    HCContent Status !TypedContent   
    HCError ErrorResponse    
    HCSendFile ContentType FilePath (Maybe FilePart)     
    HCRedirect Status Text   
    HCCreated Text   
    HCWai Response   
    HCWaiApp Application

ErrorResponse具有以下构造函数:

data ErrorResponse:
    NotFound     
    InternalError Text   
    InvalidArgs [Text]   
    NotAuthenticated     
    PermissionDenied Text    
    BadMethod Method    

因此,您可以throwIO发现有限数量的错误,并且错误消息仅限于Text