何时使用'ioError.userError'而不是'error'

Dan*_*rro 4 error-handling haskell

在阅读network的源代码时,我注意到ioError (userError ("Error description"))在IO操作期间引发错误的广泛使用.

由于这不是我第一次看到这个,我想知道使用这个模式而不是函数的实践有什么不同.errorPrelude

我知道,ioError . userError引发IOExceptionIO单子,同时error提出了一个ErrorCall在任何地方,但最终双方似乎注定中止显示一个简单的错误消息的程序.

哪种情况ioError . userError会有利error

Nik*_*kov 8

通常error仅用于表示错误.从某种意义上讲,开发人员期望永远不会发生的事情就是一个错误.虽然error确实只是抛出一个ErrorCall异常,因为它可以像任何其他异常一样被捕获,但通常永远不会捕获它,因此程序崩溃通知最终用户有关作为参数提供的消息的错误error.稍后,用户可以在问题跟踪器上发布该信息.

IOException另一方面,s意味着被捕获,只是标准C/Java控制流程的改编.在userError通常用于指定一些一般情况下,当没有任何的多种特定类型AlreadyExistsResourceBusy是合适的.


必须提到的是,针对这两个问题的解决方案已经发展.

对于错误报告,存在基于TemplateHaskell的库,例如loch-th占位符,它们扩展它error以引用源代码中的特定位置和其他细节,例如"todo"dummies,它们让编译通过,但是警告.

任何类型的例外通常被认为是对其他整洁的Haskell类型系统的攻击.最大的问题是你和编译器都没有关于某些计算的信息,例如IO (),会引发任何类型的异常.事实证明这是非常糟糕的,一些低级库引发的异常模式的出现深深地嵌套在依赖关系层次结构中,然后触发了一系列关于不同项目的错误报告并造成大量痛苦.这就是为什么最近基于异常的控制流的完全替换已经开发出来的原因,例如具有相关错误 util-library的EitherTmonad变换器变换器.这两种解决方案都会在类型系统中明确表示异常.该然而,已收到一些批评赞成+"错误".ErrorTErrorTEitherT

  • 您还可以注意到haskell.org所说的内容:`IOException记录更具体的错误类型,描述性字符串以及标记错误时使用的句柄.此外,这里是描述[Haskell异常处理]的SO链接( http://stackoverflow.com/questions/6009384/exception-handling-in-haskell) (3认同)
  • 然后,按照惯例,你可以说,一个`ErrorCall`被假定永远不会被捕获,但它可以捕获一个`userError`并对它进行一些处理吗? (2认同)