euv_core/reactive/error_boundary/
impl.rs1use super::*;
2
3impl ErrorBoundary {
4 pub fn new() -> Self {
7 Self {
8 phase: Signal::create(ErrorBoundaryPhase::Healthy),
9 }
10 }
11
12 pub fn phase(&self) -> Signal<ErrorBoundaryPhase> {
14 self.phase.clone()
15 }
16
17 pub fn current(&self) -> ErrorBoundaryPhase {
19 self.phase.get()
20 }
21
22 pub fn is_healthy(&self) -> bool {
24 matches!(self.phase.get(), ErrorBoundaryPhase::Healthy)
25 }
26
27 pub fn is_caught(&self) -> bool {
29 matches!(self.phase.get(), ErrorBoundaryPhase::Caught(_))
30 }
31
32 pub fn try_with<F, R>(&self, closure: F) -> Result<R, String>
40 where
41 F: FnOnce() -> R + std::panic::UnwindSafe,
42 {
43 match std::panic::catch_unwind(closure) {
44 Ok(value) => Ok(value),
45 Err(payload) => {
46 let message = extract_message(&payload);
47 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
48 self.phase.set(ErrorBoundaryPhase::Caught(message.clone()));
49 }));
50 Err(message)
51 }
52 }
53 }
54
55 pub fn reset(&self) {
59 let _ = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
60 self.phase.set(ErrorBoundaryPhase::Healthy);
61 }));
62 }
63}
64
65impl Default for ErrorBoundary {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71impl std::fmt::Display for ErrorBoundary {
72 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 write!(formatter, "ErrorBoundary({:?})", self.phase.get())
74 }
75}
76
77impl Default for ErrorBoundaryPhase {
78 fn default() -> Self {
79 ErrorBoundaryPhase::Healthy
80 }
81}
82
83impl PartialEq for ErrorBoundaryPhase {
84 fn eq(&self, other: &Self) -> bool {
85 match (self, other) {
86 (ErrorBoundaryPhase::Healthy, ErrorBoundaryPhase::Healthy) => true,
87 (ErrorBoundaryPhase::Caught(a), ErrorBoundaryPhase::Caught(b)) => a == b,
88 _ => false,
89 }
90 }
91}