11use crate :: runtime:: blocking:: { BlockingTask , NoopSchedule } ;
22use crate :: runtime:: task:: { self , JoinHandle } ;
33use crate :: runtime:: { blocking, context, driver, Spawner } ;
4- use crate :: util:: error:: CONTEXT_MISSING_ERROR ;
4+ use crate :: util:: error:: { CONTEXT_MISSING_ERROR , THREAD_LOCAL_DESTROYED_ERROR } ;
55
66use std:: future:: Future ;
77use std:: marker:: PhantomData ;
@@ -110,7 +110,7 @@ impl Handle {
110110 /// # }
111111 /// ```
112112 pub fn current ( ) -> Self {
113- context:: current ( ) . expect ( CONTEXT_MISSING_ERROR )
113+ context:: current ( )
114114 }
115115
116116 /// Returns a Handle view over the currently running Runtime
@@ -119,7 +119,7 @@ impl Handle {
119119 ///
120120 /// Contrary to `current`, this never panics
121121 pub fn try_current ( ) -> Result < Self , TryCurrentError > {
122- context:: current ( ) . ok_or ( TryCurrentError ( ( ) ) )
122+ context:: try_current ( )
123123 }
124124
125125 cfg_stats ! {
@@ -334,17 +334,60 @@ impl Handle {
334334}
335335
336336/// Error returned by `try_current` when no Runtime has been started
337- pub struct TryCurrentError ( ( ) ) ;
337+ #[ derive( Debug ) ]
338+ pub struct TryCurrentError {
339+ kind : TryCurrentErrorKind ,
340+ }
341+
342+ impl TryCurrentError {
343+ pub ( crate ) fn new_no_context ( ) -> Self {
344+ Self {
345+ kind : TryCurrentErrorKind :: NoContext ,
346+ }
347+ }
338348
339- impl fmt:: Debug for TryCurrentError {
349+ pub ( crate ) fn new_thread_local_destroyed ( ) -> Self {
350+ Self {
351+ kind : TryCurrentErrorKind :: ThreadLocalDestroyed ,
352+ }
353+ }
354+
355+ /// Returns true if the call failed because there is currently no runtime in
356+ /// the Tokio context.
357+ pub fn is_missing_context ( & self ) -> bool {
358+ matches ! ( self . kind, TryCurrentErrorKind :: NoContext )
359+ }
360+
361+ /// Returns true if the call failed because the Tokio context thread-local
362+ /// had been destroyed. This can usually only happen if in the destructor of
363+ /// other thread-locals.
364+ pub fn is_thread_local_destroyed ( & self ) -> bool {
365+ matches ! ( self . kind, TryCurrentErrorKind :: ThreadLocalDestroyed )
366+ }
367+ }
368+
369+ enum TryCurrentErrorKind {
370+ NoContext ,
371+ ThreadLocalDestroyed ,
372+ }
373+
374+ impl fmt:: Debug for TryCurrentErrorKind {
340375 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
341- f. debug_struct ( "TryCurrentError" ) . finish ( )
376+ use TryCurrentErrorKind :: * ;
377+ match self {
378+ NoContext => f. write_str ( "NoContext" ) ,
379+ ThreadLocalDestroyed => f. write_str ( "ThreadLocalDestroyed" ) ,
380+ }
342381 }
343382}
344383
345384impl fmt:: Display for TryCurrentError {
346385 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
347- f. write_str ( CONTEXT_MISSING_ERROR )
386+ use TryCurrentErrorKind :: * ;
387+ match self . kind {
388+ NoContext => f. write_str ( CONTEXT_MISSING_ERROR ) ,
389+ ThreadLocalDestroyed => f. write_str ( THREAD_LOCAL_DESTROYED_ERROR ) ,
390+ }
348391 }
349392}
350393
0 commit comments