9

I am a Haskell newbie.

I am trying to write a small Webdav server using the Yesod Framework and modelled after the WebdavServlet in the Apache Tomcat 7 source code. I have run into a problem returning an error from one of my functions.

My webdav service should return either XML or JSON, depending on the value of the Accept header sent in by the caller. I defined a data type called RepXmlJson:

import Yesod

data RepXmlJson = RepXmlJson RepXml RepJson

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

I am using this data type as the return value of my services, specifically the lockWebdavR function. I am trying to return a status 423 (locked) if a resource is currently locked. My code looks like this:

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

I am getting the following error:

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 searched through the book "Developing Web Applications with Haskell and Yesod", but cannot find an example of returning an error of the proper type (Rep...).

How do I create a RepXmlJson with the correct error status?

4

1 回答 1

5

处理程序的正常完成总是导致 200 状态代码。要覆盖它,您必须以其他方式发送响应。在您的情况下,您可以尝试sendResponseStatus. 其他可能性是sendWaiResponseand redirectWith,尽管我怀疑后者是否有用。

于 2012-11-07T12:52:02.543 回答