Skip to main content

matter_controller/
error.rs

1//! Error type for `matter-controller`.
2
3use crate::store::StoreError;
4
5/// Errors surfaced by the controller's persistence and identity layer.
6///
7/// `#[non_exhaustive]` so later sub-phases can add networked variants
8/// (e.g. `SessionLost`, `DeviceUnreachable`) without a breaking change.
9#[derive(Debug, thiserror::Error)]
10#[non_exhaustive]
11pub enum Error {
12    /// The backing [`ControllerStore`](crate::store::ControllerStore) failed.
13    #[error("store error: {0}")]
14    Store(#[from] StoreError),
15
16    /// TLV encode/decode of the snapshot blob failed.
17    #[error("TLV codec error: {0}")]
18    Codec(#[from] matter_codec::Error),
19
20    /// A certificate failed to parse or serialize.
21    #[error("certificate error: {0}")]
22    Cert(#[from] matter_cert::Error),
23
24    /// NOC/RCAC issuance failed.
25    #[error("NOC issuance error: {0}")]
26    Noc(#[from] matter_commissioning::NocError),
27
28    /// A signing key could not be generated or reconstructed.
29    #[error("signer error: {0}")]
30    Signer(String),
31
32    /// The persisted snapshot was structurally invalid or an unknown version.
33    #[error("malformed snapshot: {0}")]
34    Snapshot(String),
35
36    /// CASE session establishment failed, or a driver operation errored.
37    #[error("driver error: {0}")]
38    Driver(#[from] matter_commissioning::driver::DriverError),
39
40    /// A transport / session-manager (framing, MRP) operation failed.
41    #[error("transport error: {0}")]
42    Transport(#[from] matter_transport::Error),
43
44    /// No fabric exists, or the requested node/fabric is not addressable.
45    #[error("not commissioned: {0}")]
46    NotCommissioned(String),
47
48    /// The owning controller task has stopped (channel closed).
49    #[error("controller task is no longer running")]
50    ControllerStopped,
51
52    /// An Interaction-Model request/response failed to build or parse.
53    #[error("interaction model error: {0}")]
54    InteractionModel(#[from] matter_interaction::ImError),
55
56    /// An operational-path failure with a human-readable detail — a key
57    /// derivation (operational IPK / compressed fabric id), a transport/session
58    /// send or decode, a request timeout, or a subscription liveness timeout.
59    #[error("operational error: {0}")]
60    Operational(String),
61
62    /// Attestation trust material could not be loaded.
63    #[error("attestation trust error: {0}")]
64    Trust(String),
65
66    /// The setup code (QR / manual) could not be parsed.
67    #[error("invalid setup code: {0}")]
68    SetupCode(String),
69
70    /// Commissioning requires attestation trust, but none was configured.
71    #[error("no attestation trust configured (use MatterController::builder)")]
72    NoTrust,
73
74    /// An `AdministratorCommissioning` command returned a non-success IM status
75    /// (e.g. 0x02 Busy, 0x03 `PAKEParameterError`, 0x04 `WindowNotOpen` reported as
76    /// a cluster status). The raw IM status byte is preserved.
77    #[error("commissioning window command rejected (IM status {0:#04x})")]
78    CommissioningWindowRejected(u8),
79
80    /// Refused to remove the controller's own fabric (would sever the CASE
81    /// session and orphan persisted device state). No `force` override exists.
82    #[error("refusing to remove our own fabric (would orphan the device)")]
83    WouldRemoveSelf,
84
85    /// An `OperationalCredentials` command returned a non-success
86    /// `NodeOperationalCertStatusEnum` (e.g. 7 `InvalidFabricIndex`). Raw code preserved.
87    #[error("operational-credentials command rejected (status {0})")]
88    OperationalCredentialsRejected(u8),
89
90    /// Refused an ACL write that would strip our own administrative access
91    /// (no Administer/CASE entry covering our commissioner node id). Prevents
92    /// orphaning the device. Checked before any bytes are sent.
93    #[error("refusing ACL write: it would remove our own administrative access")]
94    AclWouldLockOut,
95
96    /// A `Groups` / `GroupKeyManagement` command returned a non-success status
97    /// (e.g. `ResourceExhausted` from `MaxGroupsPerFabric`). Raw status preserved.
98    #[error("group command rejected (status {0})")]
99    GroupCommandRejected(u8),
100
101    /// A group send (`invoke_group`) named a `key_set_id` that has not been
102    /// provisioned on the controller's fabric (no matching
103    /// [`GroupKeySetConfig`](crate::GroupKeySetConfig) in `group_keys`). Call
104    /// [`MatterController::create_group`](crate::MatterController::create_group)
105    /// first to mint and persist the key set.
106    #[error("group key set {0} is not provisioned on this fabric")]
107    GroupNotProvisioned(u16),
108}