【问题标题】:Returning an error status in Haskell and Yesod在 Haskell 和 Yesod 中返回错误状态
【发布时间】:2012-11-07 20:52:02
【问题描述】:

我是 Haskell 新手。

我正在尝试使用Yesod Framework 编写一个小型Webdav 服务器,并以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

【问题讨论】:

    标签: haskell http-status-codes yesod


    【解决方案1】:

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

    【讨论】:

    • 我将返回值更改为 sendResponseStatus webdavLocked423 $ RepXmlJson (RepXml "") (RepJson "") 并编译。谢谢。顺便说一句,好书。
    • 我使用 invalidArgs ["Could not parse refs"] 来响应 400 错误。但是不明白我的消息会发生什么...
    猜你喜欢
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 2015-10-13
    • 2012-08-25
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多