2012-11-07 36 views
8

我是一個Haskell新手。在Haskell和Yesod中返回一個錯誤狀態

我正在嘗試編寫一個小型的Webdav服務器,它使用Yesod Framework並且在Apache Tomcat 7源代碼中的WebdavServlet之後建模。我遇到了一個問題,從我的一個函數返回一個錯誤。

我的webdav服務應返回XML或JSON,具體取決於調用者發送的Accept頭的值。我定義了名爲RepXmlJson數據類型:

import Yesod 

data RepXmlJson = RepXmlJson RepXml RepJson 

instance HasReps RepXmlJson where 
    chooseRep (RepXmlJson (RepXml xml) (RepJson json)) = chooseRep 
    [ (typeXml, xml) 
    , (typeJson, json) 
    ] 

我使用這種數據類型爲我服務的返回值,特別是lockWebdavR功能。我試圖返回一個狀態423(鎖定),如果資源當前被鎖定。我的代碼如下所示:

import qualified Data.ByteString as B 
import qualified Data.Map  as M 
import qualified Data.Text  as T 
import qualified Network.Wai  as W 

mkYesodSub "Webdav" [] [parseRoutes| 
/WebdavR COPY DELETE LOCK MKCOL MOVE OPTIONS PROPFIND PROPPATCH PUT UNLOCK 
|] 

type WebdavHandler yesod = GHandler Webdav yesod 

webdavLocked423 :: Status 
webdavLocked423 = Status 423 "Locked" 

isLockedRequest :: Yesod master => Request -> WebdavHandler master Bool 
-- isLockedRequest definition omitted for brevity 

lockWebdavR :: Yesod master => WebdavHandler master RepXmlJson 
lockWebdavR = do 
    request <- getRequest 
    locked <- isLockedRequest request 
    if locked 
    then return $ 
     W.responseLBS webdavLocked423 [("Content-Type", "text/plain")] "" 
    else return undefined 

我收到以下錯誤:

Webdav.hs:94:10: 
    Couldn't match expected type `RepXmlJson' 
       with actual type `W.Response' 
    Expected type: GHandler Webdav master RepXmlJson 
     Actual type: GHandler Webdav master W.Response 
    In the expression: 
     return 
     $ W.responseLBS webdavLocked423 [("Content-Type", "text/plain")] "" 
    In a stmt of a 'do' block: 
     if locked then 
      return 
      $ W.responseLBS webdavLocked423 [("Content-Type", "text/plain")] "" 
     else 
      return undefined 

我通過這本書"Developing Web Applications with Haskell and Yesod"搜查,但找不到返回正確類型的錯誤的例子(Rep...) 。

如何創建具有正確錯誤狀態的RepXmlJson

回答

5

正常完成一個處理程序總是會產生一個200狀態碼。要覆蓋它,你必須以其他方式發送響應。在你的情況下,你可以試試sendResponseStatus。其他可能性將是sendWaiResponseredirectWith,但我懷疑後者會有用。

+0

我將返回值更改爲'sendResponseStatus webdavLocked423 $ RepXmlJson(RepXml「」)(RepJson「」)'並編譯。謝謝。順便說一句,好書。 – Ralph

+0

我使用'invalidArgs [「無法解析refs」]'迴應400錯誤。但不明白我的消息會發生什麼... – cies