cellular_raza_concepts/
errors.rs1use core::fmt::Display;
2use std::error::Error;
3
4macro_rules! define_errors {
5 ($(($err_name: ident, $err_descr: expr)),+) => {
6 $(
7 #[doc = $err_descr]
8 #[derive(Debug,Clone)]
9 pub struct $err_name(
10 #[doc = "Error message associated with "]
11 #[doc = stringify!($err_name)]
12 #[doc = " error type."]
13 pub String,
14 );
15
16 impl Display for $err_name {
17 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
18 write!(f, "{}", self.0)
19 }
20 }
21
22 impl Error for $err_name {}
23 )+
24 }
25}
26
27#[derive(Clone, Debug)]
29pub enum DecomposeError {
30 Generic(String),
32 BoundaryError(BoundaryError),
34 IndexError(IndexError),
36}
37
38impl Display for DecomposeError {
39 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40 let message = match self {
41 DecomposeError::Generic(m) => m,
42 DecomposeError::BoundaryError(b) => &format!("{b}"),
43 DecomposeError::IndexError(i) => &format!("{i}"),
44 };
45 write!(f, "{}", message)
46 }
47}
48
49impl Error for DecomposeError {}
50
51impl From<BoundaryError> for DecomposeError {
52 fn from(value: BoundaryError) -> Self {
53 DecomposeError::BoundaryError(value)
54 }
55}
56
57impl From<IndexError> for DecomposeError {
58 fn from(value: IndexError) -> Self {
59 DecomposeError::IndexError(value)
60 }
61}
62
63define_errors!(
64 (SetupError, "Occurs during setup of a new simulation"),
65 (CalcError, "General Calculation Error"),
66 (
67 TimeError,
68 "Error related to advancing the simulation time or displaying its progress"
69 ),
70 (DivisionError, "Errors related to a cell dividing process"),
75 (
76 DeathError,
77 "Errors occurring during the final death step of a cell"
78 ),
79 (
80 IndexError,
81 "Can occur internally when information is not present at expected place"
82 ),
83 (
84 RequestError,
85 "Ask the wrong object for information and receive this error"
86 ),
87 (
88 CommunicationError,
89 "Error which occurs during sending, receiving or transmitting information between threads"
90 ),
91 (BoundaryError, "Can occur during boundary calculation"),
92 (
93 ControllerError,
94 "Occurs when incorrectly applying a controller effect"
95 ),
96 (DrawingError, "Used to catch errors related to plotting"),
97 (
98 RngError,
99 "Can occur when generating distributions or drawing samples from them."
100 )
101);
102
103impl From<String> for TimeError {
104 fn from(value: String) -> Self {
105 TimeError(value)
106 }
107}
108
109impl From<std::io::Error> for DecomposeError {
110 fn from(value: std::io::Error) -> Self {
111 DecomposeError::BoundaryError(BoundaryError(format!("{}", value)))
112 }
113}
114
115impl From<CalcError> for SetupError {
116 fn from(value: CalcError) -> Self {
117 SetupError(format!("{}", value))
118 }
119}
120
121#[cfg(feature = "plotters")]
122#[cfg_attr(docsrs, doc(cfg(feature = "plotters")))]
123impl<E> From<plotters::drawing::DrawingAreaErrorKind<E>> for DrawingError
124where
125 E: Error + Send + Sync,
126{
127 fn from(drawing_error: plotters::drawing::DrawingAreaErrorKind<E>) -> DrawingError {
128 DrawingError(drawing_error.to_string())
129 }
130}
131
132#[doc(hidden)]
134#[macro_export]
135macro_rules! format_error_message(
136 (@function) => {
137 {
138 fn f() {}
139 let name = std::any::type_name_of_val(&f);
140 name.strip_suffix("::f").unwrap()
141 }
142 };
143 ($bug_title:expr, $error_msg:expr) => {
144 {let __cr_private_error = {
147 let title = $bug_title.replace(" ", "%20");
148 let mut body = String::from($error_msg);
149 body = body + &format!("%0A%0AFile: {}", file!());
150 body = body + &format!("%0ALine: {}", line!());
151 body = body + &format!("%0AColumn: {}", column!());
152 body = body.replace(" ", "%20");
153 format!("Internal Error in file {} function {}: +++ {} +++ Please file a bug-report: \
154 https://github.com/jonaspleyer/cellular_raza/issues/new?\
155 title={}&body={}",
156 format_error_message!(@function),
157 file!(),
158 $error_msg,
159 title,
160 body,
161 )
162 };
163 __cr_private_error
170 }
171 };
172);