Skip to main content

standard_plugin/
error.rs

1//! The error every fallible SDK call returns.
2
3use alloc::string::String;
4use core::fmt;
5
6use crate::surface::Model;
7
8/// Why a host call or a surface operation did not run.
9#[derive(Clone, Debug, PartialEq, Eq)]
10#[non_exhaustive]
11pub enum Error {
12    /// The manifest does not carry the grant the call needs. `grant` names
13    /// it (`values.read:git.main`, `account.read`, ...): add it to
14    /// `standard-plugin.json` with a reason.
15    GrantDenied { grant: String },
16    /// The per-plugin rate limit for this call kind was reached.
17    RateLimited,
18    /// The backing service is not reachable right now.
19    Unavailable(String),
20    /// The host rejected the arguments (an unknown surface id, an oversized
21    /// value, a key outside the plugin's namespace).
22    Invalid(String),
23    /// A payload did not serialize or deserialize.
24    Json(String),
25    /// The surface has no buffer yet: the viewer has not laid it out.
26    NotAttached { surface: String },
27    /// The manifest declares the surface in the other model.
28    WrongModel {
29        surface: String,
30        expected: Model,
31        found: Model,
32    },
33}
34
35/// `Result<T, Error>`.
36pub type Result<T, E = Error> = core::result::Result<T, E>;
37
38impl Error {
39    /// The missing grant, for a [`Error::GrantDenied`].
40    pub fn denied_grant(&self) -> Option<&str> {
41        match self {
42            Self::GrantDenied { grant } => Some(grant),
43            _ => None,
44        }
45    }
46
47    pub(crate) fn json(error: serde_json::Error) -> Self {
48        Self::Json(alloc::format!("{error}"))
49    }
50}
51
52impl fmt::Display for Error {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        match self {
55            Self::GrantDenied { grant } => write!(f, "grant denied: {grant}"),
56            Self::RateLimited => f.write_str("rate limited"),
57            Self::Unavailable(reason) => write!(f, "unavailable: {reason}"),
58            Self::Invalid(reason) => write!(f, "invalid: {reason}"),
59            Self::Json(reason) => write!(f, "json: {reason}"),
60            Self::NotAttached { surface } => write!(f, "surface {surface:?} has no buffer yet"),
61            Self::WrongModel {
62                surface,
63                expected,
64                found,
65            } => write!(
66                f,
67                "surface {surface:?} is declared as {} but used as {}",
68                found.as_str(),
69                expected.as_str()
70            ),
71        }
72    }
73}
74
75impl core::error::Error for Error {}