Haskell 为什么异常处理程序无法捕获模式匹配失败?

Haskell 为什么异常处理程序无法捕获模式匹配失败?,haskell,exception,scotty,Haskell,Exception,Scotty,在这种情况下,为什么模式匹配失败没有被异常处理程序捕获 我有一个传入POST请求的处理程序,由以下人员控制: 。。。 导入符合条件的Web.Scotty作为W ... W.post“/some/endpoint“$excToStr”无法处理它!$do b ActionT LT.文本IO() excH mkErr m=catchAnyDeep m(W.text.cs.mkErr.show) excToStr::String->ActionT LT.Text IO()->ActionT LT.Tex

在这种情况下,为什么模式匹配失败没有被异常处理程序捕获

我有一个传入POST请求的处理程序,由以下人员控制:

。。。
导入符合条件的Web.Scotty作为W
...
W.post“/some/endpoint“$excToStr”无法处理它!$do
b ActionT LT.文本IO()
excH mkErr m=catchAnyDeep m(W.text.cs.mkErr.show)
excToStr::String->ActionT LT.Text IO()->ActionT LT.Text IO()
excToStr errMsg=excH(\details->errMsg”(“details”))
catchAnyDeep
来自库。我还尝试了其他函数(
catchAny
handle
catch
,等等),但没有成功。问题的关键是,当传入的body无法成功解码时(并且
decode
返回
Nothing
而不是
Just x
),模式匹配失败,因此我希望我的
extToStr
(即
excH
)将处理它,因为
catchAnyDeep
(和
catchAny
)处理任何异常(包括模式匹配失败,对吗?):

catchAny::MonadCatch m=>ma->(SomeException->ma)->ma

catchAnyDeep::(MonadCatch m,MonadIO m,NFData a)=>ma->(SomeException->ma)->ma


如果我只使用
throwString
抛出一个异常,那么它将按预期工作(捕获异常)。但是模式匹配失败会导致HTTP内部错误500,并显示消息“do expression at…..中的模式匹配失败”。如何处理模式匹配异常?

scotty操作中有两种形式的异常(类型为
ActionT Text IO
)。
IO
中存在本机异常,以及
action t
转换器添加的另一种形式。这些异常是单独处理的。接口由以下内容给出:

  • (MonadCatch m,scottyrorer e)=>MonadCatch(action t e m)
    (与之类似的是
    MonadThrow
    实例)。这表明,当您使用来自
    MonadCatch
    catch
    (或来自
    MonadThrow
    throwString
    ,以及来自安全异常库的其他变体)时,您使用的是转换后的monad
    m
    的错误处理机制,在Scotty中通常是
    IO
    (它定义了
    ActionM=ActionT文本IO

  • (Monad m,ScottyError e)=>MonadFail(ActionT e m)
    MonadFail
    是用于
    do
    块中部分模式匹配的约束。它不需要来自底层monad
    m
    MonadFail
    ,这表明与
    MonadThrow
    /
    MonadCatch
    不同,它使用了
    action
    trans提供的异常机制要捕获此异常,您必须在Scotty中查找组合符,而不是辅助库,例如