mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-10-01 12:20:39 +00:00
runtime: consolidate errors for context missing (#3441)
This commit is contained in:
parent
36cf95ab62
commit
fdde5583f8
@ -259,8 +259,7 @@ cfg_rt! {
|
|||||||
/// This function panics if there is no current reactor set and `rt` feature
|
/// This function panics if there is no current reactor set and `rt` feature
|
||||||
/// flag is not enabled.
|
/// flag is not enabled.
|
||||||
pub(super) fn current() -> Self {
|
pub(super) fn current() -> Self {
|
||||||
crate::runtime::context::io_handle()
|
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.")
|
||||||
.expect("there is no reactor running, must be called from the context of Tokio runtime")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,7 +273,7 @@ cfg_not_rt! {
|
|||||||
/// This function panics if there is no current reactor set, or if the `rt`
|
/// This function panics if there is no current reactor set, or if the `rt`
|
||||||
/// feature flag is not enabled.
|
/// feature flag is not enabled.
|
||||||
pub(super) fn current() -> Self {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ use crate::runtime::builder::ThreadNameFn;
|
|||||||
use crate::runtime::context;
|
use crate::runtime::context;
|
||||||
use crate::runtime::task::{self, JoinHandle};
|
use crate::runtime::task::{self, JoinHandle};
|
||||||
use crate::runtime::{Builder, Callback, Handle};
|
use crate::runtime::{Builder, Callback, Handle};
|
||||||
|
use crate::util::error::CONTEXT_MISSING_ERROR;
|
||||||
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -81,7 +82,7 @@ where
|
|||||||
F: FnOnce() -> R + Send + 'static,
|
F: FnOnce() -> R + Send + 'static,
|
||||||
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)
|
rt.spawn_blocking(func)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ where
|
|||||||
F: FnOnce() -> R + Send + 'static,
|
F: FnOnce() -> R + Send + 'static,
|
||||||
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));
|
let (task, _handle) = task::joinable(BlockingTask::new(func));
|
||||||
rt.blocking_spawner.spawn(task, &rt)
|
rt.blocking_spawner.spawn(task, &rt)
|
||||||
|
@ -13,9 +13,9 @@ pub(crate) fn current() -> Option<Handle> {
|
|||||||
|
|
||||||
cfg_io_driver! {
|
cfg_io_driver! {
|
||||||
pub(crate) fn io_handle() -> crate::runtime::driver::IoHandle {
|
pub(crate) fn io_handle() -> crate::runtime::driver::IoHandle {
|
||||||
CONTEXT.with(|ctx| match *ctx.borrow() {
|
CONTEXT.with(|ctx| {
|
||||||
Some(ref ctx) => ctx.io_handle.clone(),
|
let ctx = ctx.borrow();
|
||||||
None => Default::default(),
|
ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).io_handle.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,18 +23,18 @@ cfg_io_driver! {
|
|||||||
cfg_signal_internal! {
|
cfg_signal_internal! {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
pub(crate) fn signal_handle() -> crate::runtime::driver::SignalHandle {
|
pub(crate) fn signal_handle() -> crate::runtime::driver::SignalHandle {
|
||||||
CONTEXT.with(|ctx| match *ctx.borrow() {
|
CONTEXT.with(|ctx| {
|
||||||
Some(ref ctx) => ctx.signal_handle.clone(),
|
let ctx = ctx.borrow();
|
||||||
None => Default::default(),
|
ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).signal_handle.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_time! {
|
cfg_time! {
|
||||||
pub(crate) fn time_handle() -> crate::runtime::driver::TimeHandle {
|
pub(crate) fn time_handle() -> crate::runtime::driver::TimeHandle {
|
||||||
CONTEXT.with(|ctx| match *ctx.borrow() {
|
CONTEXT.with(|ctx| {
|
||||||
Some(ref ctx) => ctx.time_handle.clone(),
|
let ctx = ctx.borrow();
|
||||||
None => Default::default(),
|
ctx.as_ref().expect(crate::util::error::CONTEXT_MISSING_ERROR).time_handle.clone()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use crate::runtime::blocking::task::BlockingTask;
|
use crate::runtime::blocking::task::BlockingTask;
|
||||||
use crate::runtime::task::{self, JoinHandle};
|
use crate::runtime::task::{self, JoinHandle};
|
||||||
use crate::runtime::{blocking, context, driver, Spawner};
|
use crate::runtime::{blocking, context, driver, Spawner};
|
||||||
|
use crate::util::error::CONTEXT_MISSING_ERROR;
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
@ -97,7 +98,7 @@ impl Handle {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn current() -> Self {
|
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
|
/// Returns a Handle view over the currently running Runtime
|
||||||
@ -213,7 +214,7 @@ impl fmt::Debug for TryCurrentError {
|
|||||||
|
|
||||||
impl fmt::Display for TryCurrentError {
|
impl fmt::Display for TryCurrentError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str("no tokio Runtime has been initialized")
|
f.write_str(CONTEXT_MISSING_ERROR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::runtime;
|
use crate::runtime;
|
||||||
use crate::task::JoinHandle;
|
use crate::task::JoinHandle;
|
||||||
|
use crate::util::error::CONTEXT_MISSING_ERROR;
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ cfg_rt! {
|
|||||||
T::Output: Send + 'static,
|
T::Output: Send + 'static,
|
||||||
{
|
{
|
||||||
let spawn_handle = runtime::context::spawn_handle()
|
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");
|
let task = crate::util::trace::task(task, "task");
|
||||||
spawn_handle.spawn(task)
|
spawn_handle.spawn(task)
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ cfg_rt! {
|
|||||||
/// panicking.
|
/// panicking.
|
||||||
pub(crate) fn current() -> Self {
|
pub(crate) fn current() -> Self {
|
||||||
crate::runtime::context::time_handle()
|
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.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,8 +71,7 @@ cfg_not_rt! {
|
|||||||
/// lazy, and so outside executed inside the runtime successfuly without
|
/// lazy, and so outside executed inside the runtime successfuly without
|
||||||
/// panicking.
|
/// panicking.
|
||||||
pub(crate) fn current() -> Self {
|
pub(crate) fn current() -> Self {
|
||||||
panic!("there is no timer running, must be called from the context of Tokio runtime or \
|
panic!(crate::util::error::CONTEXT_MISSING_ERROR)
|
||||||
`rt` is not enabled")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
tokio/src/util/error.rs
Normal file
3
tokio/src/util/error.rs
Normal file
@ -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";
|
@ -35,3 +35,12 @@ pub(crate) mod trace;
|
|||||||
#[cfg(any(feature = "macros"))]
|
#[cfg(any(feature = "macros"))]
|
||||||
#[cfg_attr(not(feature = "macros"), allow(unreachable_pub))]
|
#[cfg_attr(not(feature = "macros"), allow(unreachable_pub))]
|
||||||
pub use rand::thread_rng_n;
|
pub use rand::thread_rng_n;
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "rt",
|
||||||
|
feature = "time",
|
||||||
|
feature = "net",
|
||||||
|
feature = "process",
|
||||||
|
all(unix, feature = "signal")
|
||||||
|
))]
|
||||||
|
pub(crate) mod error;
|
||||||
|
@ -84,3 +84,16 @@ fn test_drop_on_notify() {
|
|||||||
// Force the reactor to turn
|
// Force the reactor to turn
|
||||||
rt.block_on(async {});
|
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());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -7,13 +7,17 @@ use futures::executor::block_on;
|
|||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "no timer running")]
|
#[should_panic(
|
||||||
fn panics_when_no_timer() {
|
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());
|
block_on(timeout_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[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() {
|
fn panics_when_no_reactor() {
|
||||||
let srv = TcpListener::bind("127.0.0.1:0").unwrap();
|
let srv = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||||
let addr = srv.local_addr().unwrap();
|
let addr = srv.local_addr().unwrap();
|
||||||
@ -25,3 +29,11 @@ async fn timeout_value() {
|
|||||||
let dur = Duration::from_millis(20);
|
let dur = Duration::from_millis(20);
|
||||||
let _ = timeout(dur, rx).await;
|
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());
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ use tokio::sync::oneshot;
|
|||||||
use tokio_test::{assert_err, assert_ok};
|
use tokio_test::{assert_err, assert_ok};
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use tokio::time::{timeout, Duration};
|
||||||
|
|
||||||
mod support {
|
mod support {
|
||||||
pub(crate) mod mpsc_stream;
|
pub(crate) mod mpsc_stream;
|
||||||
@ -135,6 +135,21 @@ fn acquire_mutex_in_drop() {
|
|||||||
drop(rt);
|
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 {
|
fn rt() -> Runtime {
|
||||||
tokio::runtime::Builder::new_current_thread()
|
tokio::runtime::Builder::new_current_thread()
|
||||||
.enable_all()
|
.enable_all()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user