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>;