2012-11-07 8 views
8

Ich bin ein Haskell-Neuling.Zurückgeben eines Fehlerstatus in Haskell und Yesod

Ich versuche, einen kleinen Webdav Server mit der Yesod Framework zu schreiben und nach dem WebdavServlet im Apache Tomcat 7 Quellcode modelliert. Ich bin auf ein Problem gestoßen, das einen Fehler von einer meiner Funktionen zurückbringt.

Mein WebDAV-Dienst sollte entweder XML oder JSON zurückgeben, abhängig vom Wert des Headers Accept, der vom Aufrufer gesendet wurde. I definiert einen Datentyp RepXmlJson genannt:

import Yesod 

data RepXmlJson = RepXmlJson RepXml RepJson 

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

ich diesen Datentyp als Rückgabewert meiner Dienste verwende, speziell die lockWebdavR Funktion. Ich versuche, einen Status 423 (gesperrt) zurückzugeben, wenn eine Ressource derzeit gesperrt ist. Mein Code sieht wie folgt aus:

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 

Ich erhalte die folgende Fehlermeldung:

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 

ich durch das Buch gesucht "Developing Web Applications with Haskell and Yesod", kann aber nicht ein Beispiel der Rückkehr eines Fehlers des richtigen Typs (Rep...) finden .

Wie erstelle ich einen RepXmlJson mit dem korrekten Fehlerstatus?

Antwort

5

Die normale Beendigung eines Handlers führt immer zu einem Statuscode 200. Um dies zu überschreiben, müssen Sie eine andere Antwort senden. In Ihrem Fall könnten Sie versuchen sendResponseStatus. Andere Möglichkeiten wären sendWaiResponse und redirectWith, obwohl ich bezweifle, dass Letzteres nützlich sein wird.

+0

Ich habe den Rückgabewert in 'sendResponseStatus webdavLocked423 $ RepXmlJson (RepXml" ") (RepJson" ")' geändert und kompiliert. Vielen Dank. BTW, schönes Buch. – Ralph

+0

Ich benutze 'invalidArgs [" Refs konnte nicht analysiert werden "], um mit einem Fehler von 400 zu antworten. Aber verstehe nicht, was mit meiner Nachricht passiert ... – cies