首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在异步代码中使用panic::catch_unwind?

如何在异步代码中使用panic::catch_unwind?
EN

Stack Overflow用户
提问于 2020-07-29 17:40:40
回答 2查看 2.8K关注 0票数 7

在使用同步代码时,我可以像这样使用panic::catch_unwind

代码语言:javascript
复制
#[actix_rt::test]
async fn test_sync() -> Result<(), Error> {
    println!("before catch_unwind");
    let sync_result = panic::catch_unwind(|| {
        println!("inside sync catch_unwind");
        panic!("this is error")
    });
    println!("after catch_unwind");

    assert!(sync_result.is_ok());

    Ok(())
}

当我使用在catch_unwind块中执行的异步代码时,如何做同样的事情呢?我不知道如何运行块,同时也能够在块之后运行一些代码,并最终断言结果。

到目前为止,这就是我所拥有的:

代码语言:javascript
复制
#[actix_rt::test]
async fn test_async() -> Result<(), Error> {
    println!("before catch_unwind");
    let async_result = panic::catch_unwind(|| async {
        println!("inside async catch_unwind");
        panic!("this is error")
    }).await;
    println!("after catch_unwind");

    assert!(async_result.is_ok());

    Ok(())
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-29 17:47:34

不会试图直接使用它们。相反,使用FutureExt::catch_unwindStreamExt::catch_unwind

代码语言:javascript
复制
use futures::FutureExt; // 0.3.5

#[tokio::test]
async fn test_async() -> Result<(), Box<dyn std::error::Error>> {
    println!("before catch_unwind");

    let may_panic = async {
        println!("inside async catch_unwind");
        panic!("this is error")
    };

    let async_result = may_panic.catch_unwind().await;

    println!("after catch_unwind");

    assert!(async_result.is_ok());

    Ok(())
}
票数 7
EN

Stack Overflow用户

发布于 2021-03-08 11:30:06

我遇到了这个问题,谢普马斯特的回答部分奏效了。我得到了很多错误,非常复杂的描述,关于展开和不安全的转移变量。在你对被接受的答案的评论中,你也谈到了这个问题。

下面的解决办法为我解决了这个问题。我不建议在测试之外使用它,因为这种方法可能很昂贵。它使用Mutex和当前运行时(句柄)。

代码语言:javascript
复制
fn main() {}

#[cfg(test)]
mod test {
    #[tokio::test]
    async fn test() {
        env_logger::init();
        // This variable represents your complex type
        // Note that this can be a combination of types if you use a tuple or something else
        let my_complex_type = 1;

        // Wrap it all in a std::sync::Mutex
        let mutex = std::sync::Mutex::new(my_complex_type);

        // Pass the mutex in the panic unwind
        assert!(std::panic::catch_unwind(|| {
            // Now you can work with your complex type
            let my_complex_type = mutex.lock().unwrap();

            // Enter the runtime
            let handle = tokio::runtime::Handle::current();

            handle.enter();

            futures::executor::block_on(do_something(*my_complex_type));
        }).is_err());
    }

    async fn do_something(t: i32) {
        panic!();
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63159442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档