Skip to main content

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}