dioxus_core/
render_error.rs1use std::{
2 fmt::{Debug, Display},
3 sync::Arc,
4};
5
6use crate::innerlude::*;
7
8#[derive(Debug, Clone, PartialEq)]
10pub enum RenderError {
11 Error(CapturedError),
16
17 Suspended(SuspendedFuture),
19}
20
21impl Default for RenderError {
22 fn default() -> Self {
23 struct RenderAbortedEarly;
24 impl Debug for RenderAbortedEarly {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.write_str("Render aborted early")
27 }
28 }
29 impl Display for RenderAbortedEarly {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.write_str("Render aborted early")
32 }
33 }
34 impl std::error::Error for RenderAbortedEarly {}
35 Self::Error(CapturedError(Arc::new(RenderAbortedEarly.into())))
36 }
37}
38
39impl Display for RenderError {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 match self {
42 Self::Error(e) => write!(f, "Render aborted: {e}"),
43 Self::Suspended(e) => write!(f, "Component suspended: {e:?}"),
44 }
45 }
46}
47
48impl From<CapturedError> for RenderError {
49 fn from(e: CapturedError) -> Self {
50 Self::Error(e)
51 }
52}
53
54impl<E: Into<Error>> From<E> for RenderError {
55 fn from(e: E) -> Self {
56 let anyhow_err = e.into();
57
58 if let Some(suspended) = anyhow_err.downcast_ref::<SuspendedFuture>() {
59 return Self::Suspended(suspended.clone());
60 }
61
62 if let Some(render_error) = anyhow_err.downcast_ref::<RenderError>() {
63 return render_error.clone();
64 }
65
66 Self::Error(CapturedError(Arc::new(anyhow_err)))
67 }
68}
69
70#[derive(Debug, Clone)]
72pub struct CapturedError(pub Arc<Error>);
73
74impl CapturedError {
75 pub fn from_display(t: impl Display) -> Self {
77 Self(Arc::new(anyhow::anyhow!(t.to_string())))
78 }
79}
80
81#[cfg(feature = "serialize")]
82impl serde::Serialize for CapturedError {
83 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84 where
85 S: serde::Serializer,
86 {
87 serializer.serialize_str(&self.0.to_string())
88 }
89}
90
91#[cfg(feature = "serialize")]
92impl<'de> serde::Deserialize<'de> for CapturedError {
93 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
94 where
95 D: serde::Deserializer<'de>,
96 {
97 let s = String::deserialize(deserializer)?;
98 Ok(Self::from_display(s))
99 }
100}
101
102impl std::ops::Deref for CapturedError {
103 type Target = Error;
104
105 fn deref(&self) -> &Self::Target {
106 &self.0
107 }
108}
109
110impl<E: Into<Error>> From<E> for CapturedError {
111 fn from(e: E) -> Self {
112 Self(Arc::new(e.into()))
113 }
114}
115
116impl std::fmt::Display for CapturedError {
117 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118 std::fmt::Display::fmt(&*self.0, f)
119 }
120}
121
122impl PartialEq for CapturedError {
123 fn eq(&self, other: &Self) -> bool {
124 Arc::ptr_eq(&self.0, &other.0)
125 }
126}
127
128#[test]
129fn assert_errs_can_downcast() {
130 fn assert_is_stderr_like<T: Send + Sync + Display + Debug>() {}
131
132 assert_is_stderr_like::<RenderError>();
133 assert_is_stderr_like::<CapturedError>();
134}