From 984cd001d49a9f6e450c6dca6852d056fb301eee Mon Sep 17 00:00:00 2001 From: John Nunley Date: Thu, 16 Nov 2023 17:41:24 -0800 Subject: [PATCH 1/2] Propagate panics in tasks After smol-rs/async-task#37 I meant to add this to the executor. This commit makes it so all panics are surfaced in the tasks that the user calls. Hopefully this improves ergonomics. Signed-off-by: John Nunley --- src/lib.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dcc1f99..7116794 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,7 @@ use std::sync::{Arc, Mutex, RwLock, TryLockError}; use std::task::{Poll, Waker}; use async_lock::OnceCell; -use async_task::Runnable; +use async_task::{Builder, Runnable}; use concurrent_queue::ConcurrentQueue; use futures_lite::{future, prelude::*}; use slab::Slab; @@ -159,7 +159,11 @@ impl<'a> Executor<'a> { }; // Create the task and register it in the set of active tasks. - let (runnable, task) = unsafe { async_task::spawn_unchecked(future, self.schedule()) }; + let (runnable, task) = unsafe { + Builder::new() + .propagate_panic(true) + .spawn_unchecked(|()| future, self.schedule()) + }; active.insert(runnable.waker()); runnable.schedule(); @@ -402,7 +406,11 @@ impl<'a> LocalExecutor<'a> { }; // Create the task and register it in the set of active tasks. - let (runnable, task) = unsafe { async_task::spawn_unchecked(future, self.schedule()) }; + let (runnable, task) = unsafe { + Builder::new() + .propagate_panic(true) + .spawn_unchecked(|()| future, self.schedule()) + }; active.insert(runnable.waker()); runnable.schedule(); From 082d0b274e002d4060f768276513a70ea2360c74 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Mon, 20 Nov 2023 20:03:34 -0800 Subject: [PATCH 2/2] Add a test for panic forwarding Signed-off-by: John Nunley --- tests/panic_prop.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/panic_prop.rs diff --git a/tests/panic_prop.rs b/tests/panic_prop.rs new file mode 100644 index 0000000..eab4901 --- /dev/null +++ b/tests/panic_prop.rs @@ -0,0 +1,14 @@ +use async_executor::Executor; +use futures_lite::{future, prelude::*}; + +#[test] +fn test_panic_propagation() { + let ex = Executor::new(); + let task = ex.spawn(async { panic!("should be caught by the task") }); + + // Running the executor should not panic. + assert!(ex.try_tick()); + + // Polling the task should. + assert!(future::block_on(task.catch_unwind()).is_err()); +}