【发布时间】:2016-07-21 21:21:03
【问题描述】:
在我的overflower_support crate 的测试中,我发现我收到了很多关于已使用std::panic::catch_unwind(_) 处理的恐慌的虚假报告。这有点不幸,因为它掩盖了可能发生的真正错误。消息如下所示:
thread 'safe' panicked at 'arithmetic overflow', src/lib.rs:56
为了平息那些令人分心的消息,我引入了dont_panic(..) 函数,它劫持恐慌处理程序,调用闭包并在完成后重置恐慌处理程序,返回闭包结果。它看起来像这样:
fn dont_panic<F, A, R>(args: A, f: F) -> R
where F: Fn(A) -> R
{
let p = panic::take_hook();
panic::set_hook(Box::new(|_| ()));
let result = f(args);
panic::set_hook(p);
result
}
但是,在函数内使用这个函数来检查有些令人惊讶的是,不仅平息了想要的消息,而且quickcheck的错误输出,这对我来说显然很有价值。即使将测试限制为一个线程也会发生这种情况。
#[test]
fn test_some_panic() {
fn check(x: usize) -> bool {
let expected = if x < 256 { Some(x) } else { None };
let actual = dont_panic(|| panic::catch_unwind(|| { assert!(x < 256); x }).ok());
expected == actual
}
quickcheck(check as fn(usize) -> bool);
}
如何在保持 QuickCheck 的恐慌可见的同时从我的代码中隐藏捕获的恐慌?
【问题讨论】:
-
您能否提供一个可重现的代码示例?如果您将
quickcheck::quickcheck包装在dont_panic中,那么您的处理程序正在压缩错误消息是有道理的,因为quickcheck的合同会因失败而恐慌。也许您可能会从QuickCheck.quicktest中获得更多的收益,它会返回Result而不是恐慌。 -
我将
dont_panic(..)中的panic::catch_unwind(_)调用包装在fn check((usize, usize)) -> bool函数中,以供quickcheck::quickcheck检查 -
添加了一个几乎完整的示例(应该运行一次
use std::panic;)。