Struct ExceptionContext

Source
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>

Source

pub const fn new( local: &'static LocalKey<ExceptionContext<E>>, ) -> ExceptionContext<E>

Create a new exception context from a thread-local unsync context.

Source

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)
})
Source

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§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.