Skip to main content

arcbox_vm_driver/
error.rs

1//! The one error type every port method speaks.
2//!
3//! There is deliberately no `Unsupported` variant: a driver that cannot do
4//! something says so through a capability accessor returning `None`, never
5//! through an error at call time.
6
7use crate::capability::CheckpointFormat;
8use crate::driver::VmState;
9use crate::spec::VmId;
10
11/// Errors raised by drivers, handles, and the guest-network port.
12#[derive(Debug, thiserror::Error)]
13pub enum Error {
14    /// A [`crate::VmSpec`] (or a piece of it) failed validation.
15    #[error("invalid spec: {0}")]
16    InvalidSpec(String),
17
18    /// No VM with this id is known to the driver or network.
19    #[error("vm {0} not found")]
20    NotFound(VmId),
21
22    /// The VM is in a state the operation cannot act on (dialing an exited
23    /// VM, checkpointing one that already exited).
24    #[error("vm {id} is {state}; expected {expected}")]
25    WrongState {
26        /// The VM.
27        id: VmId,
28        /// Where it actually is.
29        state: VmState,
30        /// What the operation needed, e.g. `"running"`.
31        expected: &'static str,
32    },
33
34    /// A restore was asked of a checkpoint another driver (or another
35    /// version of this one) wrote.
36    #[error("checkpoint format {0} is not one this driver wrote")]
37    ForeignCheckpoint(CheckpointFormat),
38
39    /// The adapter itself failed: process spawn, API call, file staging.
40    ///
41    /// `driver` is the adapter's [`crate::VmDriver::name`]; `source` carries
42    /// the underlying error when there is one worth chaining.
43    #[error("driver `{driver}`: {message}")]
44    Driver {
45        /// The adapter that raised the error.
46        driver: &'static str,
47        /// What failed, in the adapter's words.
48        message: String,
49        /// The underlying error, if any.
50        #[source]
51        source: Option<Box<dyn std::error::Error + Send + Sync>>,
52    },
53
54    /// A host I/O failure surfaced unchanged.
55    #[error(transparent)]
56    Io(#[from] std::io::Error),
57
58    /// The guest-network port refused or failed an operation.
59    #[error("network: {0}")]
60    Network(String),
61
62    /// The operation cannot proceed yet, and retrying later is the remedy:
63    /// a startup-cleanup gate still closed, a same-id cleanup the host has
64    /// not finalized. Separate from [`Self::Network`] because a caller
65    /// surfaces it as "unavailable, come back" rather than as a fault.
66    #[error("unavailable: {0}")]
67    Unavailable(String),
68
69    /// A precondition the caller presented does not hold — a cleanup token
70    /// naming another generation, or naming one that no longer exists.
71    /// Retrying the same call never helps; the caller needs a current
72    /// token. Separate from [`Self::WrongState`], which is about where a
73    /// VM sits in its lifecycle.
74    #[error("failed precondition: {0}")]
75    PreconditionFailed(String),
76}
77
78/// `Result` specialised to this crate's [`Error`].
79pub type Result<T> = std::result::Result<T, Error>;