summaryrefslogtreecommitdiffstats
path: root/tokio/src/task
diff options
context:
space:
mode:
authorDaniel Fox Franke <dfoxfranke@gmail.com>2020-01-24 14:23:58 -0500
committerCarl Lerche <me@carllerche.com>2020-01-24 11:23:58 -0800
commit968c143acdde1905219880ba662cecb58c4aa82d (patch)
treecf391e06eadf1cf3e1a9f5443675b728099766e5 /tokio/src/task
parent6fbaac91e01ca32de58a07d93bfe2f23580e7a2d (diff)
task: add methods for inspecting JoinErrors (#2051)
Adds `is_cancelled()` and `is_panic()` methods to `JoinError`, as well as `into_panic()` and `try_into_panic()` methods which, when applicable, returns the payload of the panic.
Diffstat (limited to 'tokio/src/task')
-rw-r--r--tokio/src/task/error.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/tokio/src/task/error.rs b/tokio/src/task/error.rs
index 9a2eceae..d5f65a49 100644
--- a/tokio/src/task/error.rs
+++ b/tokio/src/task/error.rs
@@ -39,6 +39,95 @@ impl JoinError {
repr: Repr::Panic(Mutex::new(err)),
}
}
+
+ /// Returns true if the error was caused by the task being cancelled
+ pub fn is_cancelled(&self) -> bool {
+ match &self.repr {
+ Repr::Cancelled => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if the error was caused by the task panicking
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::panic;
+ ///
+ /// #[tokio::main]
+ /// async fn main() {
+ /// let err = tokio::spawn(async {
+ /// panic!("boom");
+ /// }).await.unwrap_err();
+ ///
+ /// assert!(err.is_panic());
+ /// }
+ /// ```
+ pub fn is_panic(&self) -> bool {
+ match &self.repr {
+ Repr::Panic(_) => true,
+ _ => false,
+ }
+ }
+
+ /// Consumes the join error, returning the object with which the task panicked.
+ ///
+ /// # Panics
+ ///
+ /// `into_panic()` panics if the `Error` does not represent the underlying
+ /// task terminating with a panic. Use `is_panic` to check the error reason
+ /// or `try_into_panic` for a variant that does not panic.
+ ///
+ /// # Examples
+ ///
+ /// ```should_panic
+ /// use std::panic;
+ ///
+ /// #[tokio::main]
+ /// async fn main() {
+ /// let err = tokio::spawn(async {
+ /// panic!("boom");
+ /// }).await.unwrap_err();
+ ///
+ /// if err.is_panic() {
+ /// // Resume the panic on the main task
+ /// panic::resume_unwind(err.into_panic());
+ /// }
+ /// }
+ /// ```
+ pub fn into_panic(self) -> Box<dyn Any + Send + 'static> {
+ self.try_into_panic()
+ .expect("`JoinError` reason is not a panic.")
+ }
+
+ /// Consumes the join error, returning the object with which the task
+ /// panicked if the task terminated due to a panic. Otherwise, `self` is
+ /// returned.
+ ///
+ /// # Examples
+ ///
+ /// ```should_panic
+ /// use std::panic;
+ ///
+ /// #[tokio::main]
+ /// async fn main() {
+ /// let err = tokio::spawn(async {
+ /// panic!("boom");
+ /// }).await.unwrap_err();
+ ///
+ /// if let Ok(reason) = err.try_into_panic() {
+ /// // Resume the panic on the main task
+ /// panic::resume_unwind(reason);
+ /// }
+ /// }
+ /// ```
+ pub fn try_into_panic(self) -> Result<Box<dyn Any + Send + 'static>, JoinError> {
+ match self.repr {
+ Repr::Panic(p) => Ok(p.into_inner().expect("Extracting panic from mutex")),
+ _ => Err(self),
+ }
+ }
}
impl fmt::Display for JoinError {