2014-10-20 106 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

相關問題