Skip to content

Commit

Permalink
Propagate panics in tasks (#78)
Browse files Browse the repository at this point in the history
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 <dev@notgull.net>
Signed-off-by: Alain Zscheile <fogti+devel@ytrizja.de>
  • Loading branch information
notgull authored Nov 21, 2023
1 parent 4b1cf40 commit fa117de
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
14 changes: 14 additions & 0 deletions tests/panic_prop.rs
Original file line number Diff line number Diff line change
@@ -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());
}

0 comments on commit fa117de

Please sign in to comment.