9

私はHaskellの初心者です。

Yesodフレームワークを使用して小さなWebdavサーバーを作成しようとしていますが、ApacheTomcat7のソースコードをモデルにしています。関数の1つからエラーを返す際に問題が発生しました。WebdavServlet

Accept私のwebdavサービスは、呼び出し元から送信されたヘッダーの値に応じて、XMLまたはJSONのいずれかを返す必要があります。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

「HaskellとYesodを使用したWebアプリケーションの開発」という本を検索しましたが、適切なタイプのエラーを返す例が見つかりません(Rep...)。

RepXmlJson正しいエラーステータスでを作成するにはどうすればよいですか?

4

1 に答える 1

5

ハンドラーが正常に完了すると、常に200ステータスコードになります。これをオーバーライドするには、別の方法で応答を送信する必要があります。あなたの場合、あなたは試すことができますsendResponseStatus。他の可能性はとですが、後者が役立つとは思えませんsendWaiResponseredirectWith

于 2012-11-07T12:52:02.543 に答える