pub struct ExceptionContext<E: 'static> { /* private fields */ }
Expand description
ExceptionContext
provides the context for throwing and catching exception.
This context wraps over a thread-local crate::unsync::ExceptionContext, and you can store it as a static variable, so that you don’t need to pass the context through argument.
Example:
use asynx::global::ExceptionContext;
thread_local! {static EXCEPTION_LOCAL: asynx::unsync::ExceptionContext<String> = Default::default(); }
pub static CTX: ExceptionContext<String> = ExceptionContext::new(&EXCEPTION_LOCAL);
async fn perform(success: bool) -> String {
if success {
"success".to_string()
} else {
CTX.throw("failed".to_string()).await
}
}
tokio_test::block_on(async {
let r = CTX
.catch(async {
assert_eq!("success".to_string(), perform(true).await);
perform(false).await;
unreachable!() // The previous statement throws an exception.
})
.await;
assert_eq!(Err("failed".to_string()), r)
});
Implementations§
Source§impl<E: 'static> ExceptionContext<E>
impl<E: 'static> ExceptionContext<E>
Sourcepub const fn new(
local: &'static LocalKey<ExceptionContext<E>>,
) -> ExceptionContext<E>
pub const fn new( local: &'static LocalKey<ExceptionContext<E>>, ) -> ExceptionContext<E>
Create a new exception context from a thread-local unsync context.
Sourcepub async fn throw(&self, e: E) -> !
pub async fn throw(&self, e: E) -> !
Throws an exception. You should always await
the result.
Example:
use asynx::global::ExceptionContext;
thread_local! {static EXCEPTION_LOCAL: asynx::unsync::ExceptionContext<String> = Default::default(); }
static CTX: ExceptionContext<String> = ExceptionContext::new(&EXCEPTION_LOCAL);
tokio_test::block_on(async {
let r = CTX.catch(async {
CTX.throw("failed".to_string()).await;
unreachable!()
}).await;
assert_eq!(Err("failed".to_string()), r)
})
Sourcepub fn catch<Fu: Future>(&self, f: Fu) -> Catching<E, Fu> ⓘ
pub fn catch<Fu: Future>(&self, f: Fu) -> Catching<E, Fu> ⓘ
Creates the wrapper future that catches the exception.
Example:
use asynx::global::ExceptionContext;
thread_local! {static EXCEPTION_LOCAL: asynx::unsync::ExceptionContext<String> = Default::default(); }
static CTX: ExceptionContext<String> = ExceptionContext::new(&EXCEPTION_LOCAL);
tokio_test::block_on(async {
let r = CTX.catch(async {
"success".to_string()
}).await;
assert_eq!(Ok("success".to_string()), r);
let r = CTX.catch(async {
CTX.throw("failed".to_string()).await;
unreachable!()
}).await;
assert_eq!(Err("failed".to_string()), r)
})
Like the unsync version, the catch
can be called multiple times.
use asynx::global::ExceptionContext;
thread_local! {static EXCEPTION_LOCAL: asynx::unsync::ExceptionContext<i32> = Default::default(); }
static CTX: ExceptionContext<i32> = ExceptionContext::new(&EXCEPTION_LOCAL);
tokio_test::block_on(async {
let r = CTX.catch(async {
let r = CTX.catch(async {
CTX.throw(1).await
}).await;
assert_eq!(Err(1), r);
let r = CTX.catch(async {
CTX.throw(2).await
}).await;
assert_eq!(Err(2), r);
CTX.throw(3).await;
}).await;
assert_eq!(Err(3), r)
})
Auto Trait Implementations§
impl<E> Freeze for ExceptionContext<E>
impl<E> RefUnwindSafe for ExceptionContext<E>
impl<E> Send for ExceptionContext<E>
impl<E> Sync for ExceptionContext<E>
impl<E> Unpin for ExceptionContext<E>
impl<E> UnwindSafe for ExceptionContext<E>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more