ferroui_reactiveui/unhandled_error_exception.rs
1//! `UnhandledErrorException` (`ReactiveUI.Core/UnhandledErrorException.cs`).
2
3use std::error::Error;
4use std::fmt;
5
6/// The error of a pipeline that broke because nothing handled its error
7/// (`UnhandledErrorException`): what [`RxState::default_exception_handler`](crate::RxState::default_exception_handler)
8/// panics with when an object implementing
9/// [`IHandleObservableErrors`](crate::IHandleObservableErrors) errors and nothing subscribes to
10/// its `thrown_exceptions`.
11///
12/// Deviation (DEVIATIONS.md, ReactiveUI): the inner exception is kept as its message. The error is
13/// the payload of a panic (`std::panic::panic_any`), which has to be `Send`, and the errors of the
14/// reactive libraries (`Rc<dyn Error>`) are not.
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub struct UnhandledErrorException {
17 message: String,
18 inner_exception: Option<String>,
19}
20
21impl Default for UnhandledErrorException {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl UnhandledErrorException {
28 /// The exception with the default message of .NET (`UnhandledErrorException()`).
29 pub fn new() -> Self {
30 Self { message: "Exception of type 'ReactiveUI.UnhandledErrorException' was thrown.".to_owned(), inner_exception: None }
31 }
32
33 /// The exception with `message` (`UnhandledErrorException(string)`).
34 pub fn with_message(message: impl Into<String>) -> Self {
35 Self { message: message.into(), inner_exception: None }
36 }
37
38 /// The exception with `message`, caused by `inner_exception`
39 /// (`UnhandledErrorException(string, Exception)`).
40 pub fn with_inner(message: impl Into<String>, inner_exception: &dyn Error) -> Self {
41 Self { message: message.into(), inner_exception: Some(inner_exception.to_string()) }
42 }
43
44 /// The message (`Message`).
45 pub fn message(&self) -> &str {
46 &self.message
47 }
48
49 /// The message of the error that caused this one (`InnerException.Message`).
50 pub fn inner_exception(&self) -> Option<&str> {
51 self.inner_exception.as_deref()
52 }
53}
54
55impl fmt::Display for UnhandledErrorException {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 match &self.inner_exception {
58 Some(inner) => write!(f, "{} ({inner})", self.message),
59 None => f.write_str(&self.message),
60 }
61 }
62}
63
64impl Error for UnhandledErrorException {}