Skip to content

Commit

Permalink
runtime: consolidate errors for context missing (#3441)
Browse files Browse the repository at this point in the history
  • Loading branch information
aknuds1 committed Jan 20, 2021
1 parent 36cf95a commit fdde558
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 24 deletions.
5 changes: 2 additions & 3 deletions tokio/src/io/driver/mod.rs
Expand Up @@ -259,8 +259,7 @@ cfg_rt! {
/// This function panics if there is no current reactor set and `rt` feature
/// flag is not enabled.
pub(super) fn current() -> Self {
crate::runtime::context::io_handle()
.expect("there is no reactor running, must be called from the context of Tokio runtime")
crate::runtime::context::io_handle().expect("A Tokio 1.x context was found, but IO is disabled. Call `enable_io` on the runtime builder to enable IO.")
}
}
}
Expand All @@ -274,7 +273,7 @@ cfg_not_rt! {
/// This function panics if there is no current reactor set, or if the `rt`
/// feature flag is not enabled.
pub(super) fn current() -> Self {
panic!("there is no reactor running, must be called from the context of Tokio runtime with `rt` enabled.")
panic!(crate::util::error::CONTEXT_MISSING_ERROR)
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions tokio/src/runtime/blocking/pool.rs
Expand Up @@ -9,6 +9,7 @@ use crate::runtime::builder::ThreadNameFn;
use crate::runtime::context;
use crate::runtime::task::{self, JoinHandle};
use crate::runtime::{Builder, Callback, Handle};
use crate::util::error::CONTEXT_MISSING_ERROR;

use std::collections::{HashMap, VecDeque};
use std::fmt;
Expand Down Expand Up @@ -81,7 +82,7 @@ where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let rt = context::current().expect("not currently running on the Tokio runtime.");
let rt = context::current().expect(CONTEXT_MISSING_ERROR);
rt.spawn_blocking(func)
}

Expand All @@ -91,7 +92,7 @@ where
F: FnOnce() -> R + Send + 'static,
R: Send + 'static,
{
let rt = context::current().expect("not currently running on the Tokio runtime.");
let rt = context::current().expect(CONTEXT_MISSING_ERROR);

let (task, _handle) = task::joinable(BlockingTask::new(func));
rt.blocking_spawner.spawn(task, &rt)
Expand Down
18 changes: 9 additions & 9 deletions tokio/src/runtime/context.rs
Expand Up @@ -13,28 +13,28 @@ pub(crate) fn current() -> Option<Handle> {

cfg_io_driver! {
pub(crate) fn io_handle() -> crate::runtime::driver::IoHandle {
CONTEXT.with(|ctx| match *ctx.borrow() {
Some(ref ctx) => ctx.io_handle.clone(),
None => Default::default(),
CONTEXT.with(|ctx| {
let ctx = ctx.borrow();
ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).io_handle.clone()
})
}
}

cfg_signal_internal! {
#[cfg(unix)]
pub(crate) fn signal_handle() -> crate::runtime::driver::SignalHandle {
CONTEXT.with(|ctx| match *ctx.borrow() {
Some(ref ctx) => ctx.signal_handle.clone(),
None => Default::default(),
CONTEXT.with(|ctx| {
let ctx = ctx.borrow();
ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).signal_handle.clone()
})
}
}

cfg_time! {
pub(crate) fn time_handle() -> crate::runtime::driver::TimeHandle {
CONTEXT.with(|ctx| match *ctx.borrow() {
Some(ref ctx) => ctx.time_handle.clone(),
None => Default::default(),
CONTEXT.with(|ctx| {
let ctx = ctx.borrow();
ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).time_handle.clone()
})
}

Expand Down
5 changes: 3 additions & 2 deletions tokio/src/runtime/handle.rs
@@ -1,6 +1,7 @@
use crate::runtime::blocking::task::BlockingTask;
use crate::runtime::task::{self, JoinHandle};
use crate::runtime::{blocking, context, driver, Spawner};
use crate::util::error::CONTEXT_MISSING_ERROR;

use std::future::Future;
use std::{error, fmt};
Expand Down Expand Up @@ -97,7 +98,7 @@ impl Handle {
/// # }
/// ```
pub fn current() -> Self {
context::current().expect("not currently running on the Tokio runtime.")
context::current().expect(CONTEXT_MISSING_ERROR)
}

/// Returns a Handle view over the currently running Runtime
Expand Down Expand Up @@ -213,7 +214,7 @@ impl fmt::Debug for TryCurrentError {

impl fmt::Display for TryCurrentError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("no tokio Runtime has been initialized")
f.write_str(CONTEXT_MISSING_ERROR)
}
}

Expand Down
3 changes: 2 additions & 1 deletion tokio/src/task/spawn.rs
@@ -1,5 +1,6 @@
use crate::runtime;
use crate::task::JoinHandle;
use crate::util::error::CONTEXT_MISSING_ERROR;

use std::future::Future;

Expand Down Expand Up @@ -129,7 +130,7 @@ cfg_rt! {
T::Output: Send + 'static,
{
let spawn_handle = runtime::context::spawn_handle()
.expect("must be called from the context of Tokio runtime configured with either `basic_scheduler` or `threaded_scheduler`");
.expect(CONTEXT_MISSING_ERROR);
let task = crate::util::trace::task(task, "task");
spawn_handle.spawn(task)
}
Expand Down
5 changes: 2 additions & 3 deletions tokio/src/time/driver/handle.rs
Expand Up @@ -47,7 +47,7 @@ cfg_rt! {
/// panicking.
pub(crate) fn current() -> Self {
crate::runtime::context::time_handle()
.expect("there is no timer running, must be called from the context of Tokio runtime")
.expect("A Tokio 1.x context was found, but timers are disabled. Call `enable_time` on the runtime builder to enable timers.")
}
}
}
Expand All @@ -71,8 +71,7 @@ cfg_not_rt! {
/// lazy, and so outside executed inside the runtime successfuly without
/// panicking.
pub(crate) fn current() -> Self {
panic!("there is no timer running, must be called from the context of Tokio runtime or \
`rt` is not enabled")
panic!(crate::util::error::CONTEXT_MISSING_ERROR)
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions tokio/src/util/error.rs
@@ -0,0 +1,3 @@
/// Error string explaining that the Tokio context hasn't been instantiated.
pub(crate) const CONTEXT_MISSING_ERROR: &str =
"there is no reactor running, must be called from the context of a Tokio 1.x runtime";
9 changes: 9 additions & 0 deletions tokio/src/util/mod.rs
Expand Up @@ -35,3 +35,12 @@ pub(crate) mod trace;
#[cfg(any(feature = "macros"))]
#[cfg_attr(not(feature = "macros"), allow(unreachable_pub))]
pub use rand::thread_rng_n;

#[cfg(any(
feature = "rt",
feature = "time",
feature = "net",
feature = "process",
all(unix, feature = "signal")
))]
pub(crate) mod error;
13 changes: 13 additions & 0 deletions tokio/tests/io_driver.rs
Expand Up @@ -84,3 +84,16 @@ fn test_drop_on_notify() {
// Force the reactor to turn
rt.block_on(async {});
}

#[test]
#[should_panic(
expected = "A Tokio 1.x context was found, but IO is disabled. Call `enable_io` on the runtime builder to enable IO."
)]
fn panics_when_io_disabled() {
let rt = runtime::Builder::new_current_thread().build().unwrap();

rt.block_on(async {
let _ =
tokio::net::TcpListener::from_std(std::net::TcpListener::bind("127.0.0.1:0").unwrap());
});
}
18 changes: 15 additions & 3 deletions tokio/tests/no_rt.rs
Expand Up @@ -7,13 +7,17 @@ use futures::executor::block_on;
use std::net::TcpListener;

#[test]
#[should_panic(expected = "no timer running")]
fn panics_when_no_timer() {
#[should_panic(
expected = "there is no reactor running, must be called from the context of a Tokio 1.x runtime"
)]
fn timeout_panics_when_no_tokio_context() {
block_on(timeout_value());
}

#[test]
#[should_panic(expected = "no reactor running")]
#[should_panic(
expected = "there is no reactor running, must be called from the context of a Tokio 1.x runtime"
)]
fn panics_when_no_reactor() {
let srv = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = srv.local_addr().unwrap();
Expand All @@ -25,3 +29,11 @@ async fn timeout_value() {
let dur = Duration::from_millis(20);
let _ = timeout(dur, rx).await;
}

#[test]
#[should_panic(
expected = "there is no reactor running, must be called from the context of a Tokio 1.x runtime"
)]
fn io_panics_when_no_tokio_context() {
let _ = tokio::net::TcpListener::from_std(std::net::TcpListener::bind("127.0.0.1:0").unwrap());
}
17 changes: 16 additions & 1 deletion tokio/tests/rt_basic.rs
Expand Up @@ -6,7 +6,7 @@ use tokio::sync::oneshot;
use tokio_test::{assert_err, assert_ok};

use std::thread;
use std::time::Duration;
use tokio::time::{timeout, Duration};

mod support {
pub(crate) mod mpsc_stream;
Expand Down Expand Up @@ -135,6 +135,21 @@ fn acquire_mutex_in_drop() {
drop(rt);
}

#[test]
#[should_panic(
expected = "A Tokio 1.x context was found, but timers are disabled. Call `enable_time` on the runtime builder to enable timers."
)]
fn timeout_panics_when_no_time_handle() {
let rt = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
rt.block_on(async {
let (_tx, rx) = oneshot::channel::<()>();
let dur = Duration::from_millis(20);
let _ = timeout(dur, rx).await;
});
}

fn rt() -> Runtime {
tokio::runtime::Builder::new_current_thread()
.enable_all()
Expand Down

0 comments on commit fdde558

Please sign in to comment.