1use std::fmt::{Debug, Display};
4
5use crate::traits::{Real, State};
6
7#[derive(PartialEq, Clone)]
9pub enum Error<T, Y>
10where
11 T: Real,
12 Y: State<T>,
13{
14 BadInput { msg: String },
16
17 MaxSteps { t: T, y: Y },
19
20 StepSize { t: T, y: Y },
22
23 Stiffness { t: T, y: Y },
25
26 OutOfBounds { t_interp: T, t_prev: T, t_curr: T },
28
29 NoLags,
31
32 InsufficientHistory { t_delayed: T, t_prev: T, t_curr: T },
34}
35
36impl<T, Y> Display for Error<T, Y>
37where
38 T: Real + Display,
39 Y: State<T> + Display,
40{
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 Self::BadInput { msg } => write!(
44 f,
45 "Bad input: {}. Check your problem definition, dimensions, and solver options.",
46 msg
47 ),
48 Self::MaxSteps { t, y } => {
49 write!(
50 f,
51 "Maximum step count reached at (t, y) = ({}, {}). Try increasing max_steps, relaxing tolerances, or shortening the integration interval.",
52 t, y
53 )
54 }
55 Self::StepSize { t, y } => write!(
56 f,
57 "Step size became too small at (t, y) = ({}, {}). This often indicates stiffness or overly tight tolerances. Consider using a stiff solver (DIRK/IRK), relaxing rtol/atol, or rescaling the problem.",
58 t, y
59 ),
60 Self::Stiffness { t, y } => write!(
61 f,
62 "Stiffness detected at (t, y) = ({}, {}). Switch to a stiff method (e.g., DIRK or IRK) or relax tolerances to improve stability.",
63 t, y
64 ),
65 Self::OutOfBounds {
66 t_interp,
67 t_prev,
68 t_curr,
69 } => {
70 write!(
71 f,
72 "Interpolation error: requested t_interp {} is outside the last step: [t_prev {}, t_curr {}]. Dense output is only valid within a completed step; request t within this interval or use t_eval to sample during integration.",
73 t_interp, t_prev, t_curr
74 )
75 }
76 Self::NoLags => write!(
77 f,
78 "Invalid DDE configuration: number of lags L must be > 0. If there are no delays, use an ODE solver instead."
79 ),
80 Self::InsufficientHistory {
81 t_delayed,
82 t_prev,
83 t_curr,
84 } => {
85 write!(
86 f,
87 "Insufficient history to interpolate at delayed time {} (window: [t_prev {}, t_curr {}]). Possible causes: max_delay is too small or history pruning is too aggressive, or steps advanced before enough history accumulated. Consider increasing max_delay, providing a longer initial history, or reducing maximum step size.",
88 t_delayed, t_prev, t_curr
89 )
90 }
91 }
92 }
93}
94
95impl<T, Y> Debug for Error<T, Y>
96where
97 T: Real + Debug,
98 Y: State<T> + Debug,
99{
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 match self {
102 Self::BadInput { msg } => write!(
103 f,
104 "Bad input: {}. Check your problem definition, dimensions, and solver options.",
105 msg
106 ),
107 Self::MaxSteps { t, y } => {
108 write!(
109 f,
110 "Maximum step count reached at (t, y) = ({:?}, {:?}). Try increasing max_steps, relaxing tolerances, or shortening the integration interval.",
111 t, y
112 )
113 }
114 Self::StepSize { t, y } => {
115 write!(
116 f,
117 "Step size became too small at (t, y) = ({:?}, {:?}). This often indicates stiffness or overly tight tolerances. Consider using a stiff solver (DIRK/IRK), relaxing rtol/atol, or rescaling the problem.",
118 t, y
119 )
120 }
121 Self::Stiffness { t, y } => {
122 write!(
123 f,
124 "Stiffness detected at (t, y) = ({:?}, {:?}). Switch to a stiff method (e.g., DIRK or IRK) or relax tolerances to improve stability.",
125 t, y
126 )
127 }
128 Self::OutOfBounds {
129 t_interp,
130 t_prev,
131 t_curr,
132 } => {
133 write!(
134 f,
135 "Interpolation error: requested t_interp {:?} is outside the last step: [t_prev {:?}, t_curr {:?}]. Dense output is only valid within a completed step; request t within this interval or use t_eval to sample during integration.",
136 t_interp, t_prev, t_curr
137 )
138 }
139 Self::NoLags => write!(
140 f,
141 "Invalid DDE configuration: number of lags L must be > 0. If there are no delays, use an ODE solver instead."
142 ),
143 Self::InsufficientHistory {
144 t_delayed,
145 t_prev,
146 t_curr,
147 } => {
148 write!(
149 f,
150 "Insufficient history to interpolate at delayed time {:?} (window: [t_prev {:?}, t_curr {:?}]). Possible causes: max_delay is too small or history pruning is too aggressive, or steps advanced before enough history accumulated. Consider increasing max_delay, providing a longer initial history, or reducing maximum step size.",
151 t_delayed, t_prev, t_curr
152 )
153 }
154 }
155 }
156}
157
158impl<T, Y> std::error::Error for Error<T, Y>
159where
160 T: Real + Debug + Display,
161 Y: State<T> + Debug + Display,
162{
163}