Skip to main content

webtrans_wasm/
error.rs

1use wasm_bindgen::prelude::*;
2
3/// A WebTransport error classified by source.
4#[derive(Clone, Debug, thiserror::Error)]
5pub enum Error {
6    #[error("webtransport session error: {0:?}")]
7    Session(web_sys::WebTransportError),
8
9    #[error("webtransport stream error: {0:?}")]
10    Stream(web_sys::WebTransportError),
11
12    #[error("web streams error: {0:?}")]
13    Streams(#[from] web_streams::Error),
14
15    #[error("unknown error: {0:?}")]
16    Unknown(JsValue),
17}
18
19impl Error {
20    /// Return the error code used when closing the stream or session.
21    pub fn code(&self) -> Option<u8> {
22        match self {
23            Error::Session(e) | Error::Stream(e) => e.stream_error_code(),
24            _ => None,
25        }
26    }
27}
28
29impl From<JsValue> for Error {
30    /// Convert a generic `JsValue` into a `WebTransportError` when possible, otherwise `Error::Unknown`.
31    fn from(v: JsValue) -> Self {
32        if let Some(e) = v.dyn_ref::<web_sys::WebTransportError>().cloned() {
33            match e.source() {
34                web_sys::WebTransportErrorSource::Stream => Error::Stream(e),
35                web_sys::WebTransportErrorSource::Session => Error::Session(e),
36                _ => Error::Unknown(v),
37            }
38        } else {
39            Error::Unknown(v)
40        }
41    }
42}
43
44#[cfg(target_family = "wasm")]
45impl webtrans_trait::Error for Error {
46    fn session_error(&self) -> Option<(u32, String)> {
47        match self {
48            Error::Session(err) => err
49                .stream_error_code()
50                .map(|code| (u32::from(code), format!("{err:?}"))),
51            _ => None,
52        }
53    }
54
55    fn stream_error(&self) -> Option<u32> {
56        match self {
57            Error::Stream(err) => err.stream_error_code().map(u32::from),
58            _ => None,
59        }
60    }
61}