处理外部库的恐慌(panic)

7
我刚开始学习Rust,并且了解到Rust默认使用panic而不是异常。我有一个依赖于外部库的Rust项目,我已经使用match语句处理了代码中所有的unwrap和?,但是我不知道如何处理来自外部库的panic。在其他语言中,我只需捕获由库抛出的异常。由于Rust默认使用panic,因此库不返回异常,而是panic并立即中止线程的执行。理想情况下,我希望能够记录并继续执行,而不是panic和中止。我尝试过以下方法:
  • catch_unwind,但这似乎不适用于外部库。
  • log-panics crate,该crate使用panic hook记录panic。我成功记录了panic,但无法阻止中止。
1个回答

13

不要惊慌

我的意思是,这才是真正的解决办法:你必须避免恐慌,而不是在它们发生时尝试从中恢复。

有些语言通常使用异常来处理防止某些操作的条件,并在不崩溃的情况下管理它们。在Rust中,这些不受支持的条件通过错误进行管理,而不是恐慌。

Rust中的panic是:

  • 最常见的是一种错误(通常是暂时的),因为您在第一次原型制作时放置了unwrap
  • 或者是一种非常特殊的条件

正如《Rust程序设计语言》所说:

当代码恐慌时,没有恢复的方法

各种实用工具(如catch_unwind)最多旨在更优雅地退出,它们不会让您的程序像什么都没有发生一样运行。

当您使用的crate恐慌时,首先检查您是否按预期使用该函数(如果您无法在不恐慌的情况下进行检查,则该库中存在错误),然后要么修复它,要么自己修复。

除了尽快崩溃外,没有合理的方式来处理恐慌。 对于您的程序生命周期中的恐慌而言,这是不寻常的。


17
抱歉,我一直想用友好易懂的大字体写上“不要惊慌”的提示。 - Denys Séguret
4
我可以建议强调,如果一个库没有提供处理(或检查)情况而不会出现紧急情况的方法,那么这是库API设计中的一个错误吗? - Kevin Reid
@KevinReid 正在尝试将它放入答案中。 - Denys Séguret
2
这是一个无关的答案。在我的情况下,web_sys或wasm_bindgen_futures中的某些内容正在发生panic,我无法重写这些库,并且panic很难复现,因此几乎不可能为这些团队生成一个合适的报告。如果我能够简单地捕获panic,我认为它可以被忽略,而不是现在必须处理有毒的互斥锁。 - Clayton Rabenda
1
@ClaytonRabenda 不,你不应该像其他语言中的异常处理一样尝试处理 panic。正如 Rust 书中所说:“当代码 panic 时,没有恢复的方法”。(https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html) - Denys Séguret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接