2012-11-07 17 views
8

Jestem nowicjuszem Haskell.Powracanie statusu błędu w Haskell i Yesod

Próbuję napisać mały serwer Webdav używając Yesod Framework i wzorowany na WebdavServlet w kodzie źródłowym Apache Tomcat 7. Wystąpił problem polegający na zwrocie błędu z jednej z moich funkcji.

Moja usługa webdav powinna zwracać wartość XML lub JSON, w zależności od wartości nagłówka Accept wysłanego przez osobę dzwoniącą. I zdefiniowany typ danych o nazwie RepXmlJson:

import Yesod 

data RepXmlJson = RepXmlJson RepXml RepJson 

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

używam tego typu danych jako wartości zwracanej z moich usług, a zwłaszcza funkcji lockWebdavR. Próbuję zwrócić status 423 (zablokowany), jeśli zasób jest aktualnie zablokowany. Mój kod wygląda następująco:

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 

otrzymuję następujący błąd:

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 

I przeszukała książki "Developing Web Applications with Haskell and Yesod", ale nie może znaleźć przykład zwrócenie błędu prawidłowego typu (Rep...) .

Jak utworzyć RepXmlJson z poprawnym stanem błędu?

Odpowiedz

5

Zwykłe ukończenie programu obsługi zawsze daje kod statusu 200. Aby to zmienić, musisz wysłać odpowiedź w inny sposób. W twoim przypadku możesz spróbować sendResponseStatus. Innymi możliwościami byłyby sendWaiResponse i redirectWith, choć wątpię, by te ostatnie były użyteczne.

+0

Zmieniłem wartość zwracaną na 'sendResponseStatus webdavLocked423 $ RepXmlJson (RepXml" ") (RepJson" ")' i kompiluje. Dzięki. Przy okazji, fajna książka. – Ralph

+0

Używam "invalidArgs [" Nie można parsować refs "]", aby odpowiedzieć z 400 błąd. Ale nie rozumiem, co dzieje się z moją wiadomością ... – cies