squib_virtio/error.rs
1//! Crate-level error type for squib-virtio.
2//!
3//! Per CLAUDE.md `ยง Error Handling`, we use `thiserror` and a single
4//! crate-rooted enum so callers can `?` from any submodule without
5//! pre-mapping. Variants are non-exhaustive so future device modules can add
6//! their own without forcing every consumer to recompile match arms.
7
8use thiserror::Error;
9
10/// All fallible operations in `squib-virtio` return [`Result<T, VirtioError>`].
11pub type Result<T> = core::result::Result<T, VirtioError>;
12
13/// Errors produced by the virtio transport, queue handling, or device frontends.
14#[derive(Debug, Error)]
15#[non_exhaustive]
16pub enum VirtioError {
17 /// Guest memory access failed (range escape, region overflow).
18 #[error(transparent)]
19 Memory(#[from] squib_core::Error),
20
21 /// A queue setup or descriptor-walk error.
22 #[error(transparent)]
23 Queue(#[from] crate::queue::QueueError),
24
25 /// Failed to deliver an IRQ to the GIC.
26 #[error("GIC delivery failed: {0}")]
27 Irq(String),
28
29 /// Device-level activation failure (resource unavailable, configuration
30 /// mismatch).
31 #[error(transparent)]
32 Activate(#[from] crate::device::ActivateError),
33
34 /// I/O backend error (host file, network socket, ...).
35 #[error("device I/O error: {0}")]
36 Io(#[from] std::io::Error),
37
38 /// Device received a malformed descriptor or request payload.
39 #[error("malformed payload: {0}")]
40 MalformedPayload(String),
41
42 /// Device received a write to a register that is invalid in the current
43 /// state machine state (e.g. configuring a queue after `DRIVER_OK`).
44 #[error("invalid driver-init transition: {0}")]
45 InvalidTransition(&'static str),
46}
47
48impl From<squib_gic::GicError> for VirtioError {
49 fn from(err: squib_gic::GicError) -> Self {
50 Self::Irq(err.to_string())
51 }
52}