Skip to main content

oxide_update_engine/
errors.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Errors generated by the engine crate.
6
7use derive_where::derive_where;
8use oxide_update_engine_types::{
9    events::Event,
10    spec::{AsError, EngineSpec},
11};
12use std::{borrow::Cow, error, fmt};
13use tokio::sync::mpsc;
14
15/// An error that occurs while the engine is being executed.
16#[derive_where(Debug)]
17pub enum ExecutionError<S: EngineSpec> {
18    StepFailed {
19        component: S::Component,
20        id: S::StepId,
21        description: Cow<'static, str>,
22        error: S::Error,
23    },
24    Aborted {
25        component: S::Component,
26        id: S::StepId,
27        description: Cow<'static, str>,
28        message: String,
29    },
30    EventSendError(mpsc::error::SendError<Event<S>>),
31}
32
33impl<S: EngineSpec> fmt::Display for ExecutionError<S> {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        match self {
36            Self::StepFailed { description, .. } => {
37                write!(f, "step failed: {description}")
38            }
39            Self::Aborted { description, message, .. } => {
40                write!(
41                    f,
42                    "execution aborted while running step \
43                     \"{description}\": {message}"
44                )
45            }
46            Self::EventSendError(_) => {
47                write!(f, "while sending event, event receiver dropped")
48            }
49        }
50    }
51}
52
53impl<S: EngineSpec> error::Error for ExecutionError<S> {
54    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
55        match self {
56            ExecutionError::StepFailed { error, .. } => Some(error.as_error()),
57            ExecutionError::Aborted { .. } => None,
58            ExecutionError::EventSendError(error) => {
59                Some(error as &(dyn error::Error + 'static))
60            }
61        }
62    }
63}
64
65impl<S: EngineSpec> From<mpsc::error::SendError<Event<S>>>
66    for ExecutionError<S>
67{
68    fn from(value: mpsc::error::SendError<Event<S>>) -> Self {
69        Self::EventSendError(value)
70    }
71}