2014-10-20 68 views
1

我有了两个部分项目:如何在Yesod路由处理程序中使用自定义错误处理程序?

  • 页面
  • API

我使用的errorHandler功能在我Yesod实例声明打造为网页错误页面当出现错误。

但是API中的所有路由都创建了JSON响应。我使用runInputPost来生成处理API输入的输入表单。当调用API时缺少参数Yesod会生成InvalidArgs异常,并返回错误的HTML页面。

我希望能够处理该异常并返回JSON如:

{ 
    "success" : False, 
    "code" : 101, 
    "message" : "The argument 'blabla' was missing" 
} 

我如何能做到这一点,且不会与它自己的errorHandler子网站?

回答

1

虽然您的解决方案肯定的作品,你可以改用runInputPostResult功能,这实际上是通过PR有人在几乎你会发现自己在同样的情况增加

+0

酷!下次我会在我的项目中碰到yesod版本时会考虑这个问题。谢谢! – rzetterberg 2014-10-20 13:53:33

+0

为了记录,该功能已经存在了一段时间。 – 2014-10-20 14:33:10

+0

更好:)我接受这个答案,因为它是Yesod中已经存在的解决方案。 – rzetterberg 2014-10-21 06:24:02

1

阅读有关如何捕捉这种情况发生在单子栈(herehere)异常之后,我发现了库exceptions这似乎易于使用。

我读到这类型Yesod实现了Exception型类,原来这是一个叫HandlerContents类型:

data HandlerContents = 
     HCContent H.Status !TypedContent 
    | HCError ErrorResponse 
    | HCSendFile ContentType FilePath (Maybe FilePart) 
    | HCRedirect H.Status Text 
    | HCCreated Text 
    | HCWai W.Response 
    | HCWaiApp W.Application 
    deriving Typeable 

我感兴趣的HCError,因为它包含ErrorResponse(相同类型的errorHandler获得) 。

我在我的cabal文件中添加了exceptions库到build-depends。我在API中的所有处理过:: Handler Value所以我创建了一个效用函数签名称为catchRouteError是我能与运行我的处理程序:

catchRouteError :: Handler Value -> Handler Value 
catchRouteError r = catch r handleError 
    where 
    handleError :: HandlerContents -> Handler Value 
    handleError (HCError (InvalidArgs _)) = ... create specific json error 
    handleError (HCError _)    = ... create generic json error 
    handleError e       = throwM e 

由于HandlerContents用于其他事情,如重定向和接收文件,我只能匹配HCError并让默认实现处理其他所有内容。

现在,我可以很容易地使用该功能运行我的处理程序:

postAPIAppStatusR :: Handler Value 
postAPIAppStatusR = catchRouteError $ do 
    ... 

这是一个快速解决我的问题,我敢肯定有一些人更好的了解Yesod可以提供更优雅的解决方案。也许你 -

+1

填写...。想要这样的事情: sendResponseStatus status400(object [“error_invalid”。= show a]) 如果你只是返回一个Aeson值,你会得到一个200响应,这是不正确的。 – 2016-03-10 13:55:46

+0

感谢您的输入,马克! – rzetterberg 2016-12-21 09:25:50

相关问题