use std::sync::Arc;
use crate::page::Page;
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ErrorDetails {
pub name: String,
pub message: String,
pub stack: String,
}
impl ErrorDetails {
#[must_use]
pub fn new(name: impl Into<String>, message: impl Into<String>, stack: impl Into<String>) -> Self {
Self {
name: name.into(),
message: message.into(),
stack: stack.into(),
}
}
}
#[derive(Clone)]
pub struct WebError {
inner: Arc<WebErrorState>,
}
struct WebErrorState {
error: ErrorDetails,
page: std::sync::Weak<Page>,
}
impl WebError {
#[must_use]
pub fn new(page: &Arc<Page>, error: ErrorDetails) -> Self {
Self {
inner: Arc::new(WebErrorState {
error,
page: Arc::downgrade(page),
}),
}
}
#[must_use]
pub fn new_detached(error: ErrorDetails) -> Self {
Self {
inner: Arc::new(WebErrorState {
error,
page: std::sync::Weak::new(),
}),
}
}
#[must_use]
pub fn page(&self) -> Option<Arc<Page>> {
self.inner.page.upgrade()
}
#[must_use]
pub fn error(&self) -> &ErrorDetails {
&self.inner.error
}
}
impl std::fmt::Debug for WebError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WebError")
.field("name", &self.inner.error.name)
.field("message", &self.inner.error.message)
.field("stack_len", &self.inner.error.stack.len())
.finish()
}
}