在servant中,如何根据Accept标头选择我的异常?

时间:2017-03-09 17:56:58

标签: haskell servant

对于上下文,这是一种身份验证情况。在我的应用程序中,如果客户端未经过身份验证,那么应用程序显然需要做出适当的响应。当我想根据调用服务器的应用程序类型选择不同的响应时,就会出现挑战。

以下是路线的示例:

server =    Header "Cookie" (AuthToken Unverified)
         :> "api" :> "history" :> Get '[HTML, JSON] HistoryPage

因此,HTML响应将用于CGI应用程序。一般来说,它应该呈现一个身份验证页面,或者它应该抛出一个303来引导用户进入身份验证页面。

但JSON响应是针对Javascript应用程序的,我想简单地返回404,因为Javascript会有其他方式进行身份验证。

这是我的顶级处理程序:

newtype WebM a = WebM (ReaderT Context (ExceptT WebExc IO) a)
data WebExc = OtherExceptionTypes
            | AppUnauthorized

runWeb :: Context -> WebM :~> Handler
runWeb ctx@Context{..} = Nat $ \(WebM action) -> withExceptT trExc $ runReaderT action ctx
  where
    trExc :: WebExc -> ServantErr
    trExc AppUnauthorized = err303 { .. }

我尝试创建自己的Javascript内容类型,但MimeRenderer不允许我抛出异常。到目前为止,我唯一的想法是捕捉"接受"标题并从处理程序中抛出303404。但这很糟糕,因为处理程序不应该知道有关实际客户端应用程序的任何信息。

有没有更清洁的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

并不完全回答你的问题,但从更大的角度来看,这听起来像是两个不同路由的用例,它们之间共享一些共同的实现。