hyperopt_core/error.rs
1use crate::StorageError;
2use std::fmt;
3
4/// Signalled by a user objective to describe how a trial ended.
5///
6/// Returning `Ok(value)` completes the trial; returning one of these marks it
7/// `Pruned` or `Failed` without aborting the whole study. A blanket `From`
8/// makes `?` on any standard error turn into [`ObjectiveError::Failed`], while
9/// [`ObjectiveError::pruned`] is used to bail out after `should_prune()`.
10#[derive(Debug)]
11pub enum ObjectiveError {
12 /// The trial was stopped early by a pruner. Marked [`crate::TrialState::Pruned`].
13 Pruned,
14 /// The objective failed. Marked [`crate::TrialState::Failed`]; the study continues.
15 Failed(Box<dyn std::error::Error + Send + Sync>),
16}
17
18impl ObjectiveError {
19 /// Convenience constructor for the pruned case:
20 /// `if ctx.should_prune() { return Err(ObjectiveError::pruned()); }`.
21 pub fn pruned() -> Self {
22 ObjectiveError::Pruned
23 }
24}
25
26impl fmt::Display for ObjectiveError {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 ObjectiveError::Pruned => write!(f, "trial pruned"),
30 ObjectiveError::Failed(e) => write!(f, "objective failed: {e}"),
31 }
32 }
33}
34
35// NB: `ObjectiveError` deliberately does *not* implement `std::error::Error`.
36// It is a control-flow signal (pruned vs. failed), and keeping it out of the
37// `Error` hierarchy is what lets the blanket `From<E: Error>` below coexist
38// with the standard `From<T> for T` — so `?` on any real error inside an
39// objective converts cleanly into `Failed`.
40impl<E> From<E> for ObjectiveError
41where
42 E: std::error::Error + Send + Sync + 'static,
43{
44 fn from(e: E) -> Self {
45 ObjectiveError::Failed(Box::new(e))
46 }
47}
48
49/// The value an objective closure returns for one trial.
50pub type ObjectiveResult = Result<f64, ObjectiveError>;
51
52/// Errors raised by [`crate::Study`] operations (currently all storage-backed).
53#[derive(Debug)]
54pub enum HyperoptError {
55 Storage(StorageError),
56}
57
58impl fmt::Display for HyperoptError {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 match self {
61 HyperoptError::Storage(e) => write!(f, "{e}"),
62 }
63 }
64}
65
66impl std::error::Error for HyperoptError {}
67
68impl From<StorageError> for HyperoptError {
69 fn from(e: StorageError) -> Self {
70 HyperoptError::Storage(e)
71 }
72}