Skip to main content

caliban_plugins/
error.rs

1//! Error type for the plugin orchestrator.
2
3use std::path::PathBuf;
4
5use thiserror::Error;
6
7/// Errors emitted by the plugin orchestrator.
8#[derive(Debug, Error)]
9pub enum PluginError {
10    /// IO failure with a contextualized path.
11    #[error("plugin io {path}: {source}")]
12    Io {
13        /// Path that triggered the failure.
14        path: PathBuf,
15        /// Underlying io error.
16        #[source]
17        source: std::io::Error,
18    },
19
20    /// JSON parse failure with a contextualized path.
21    #[error("plugin parse {path}: {source}")]
22    Parse {
23        /// Path that failed to parse.
24        path: PathBuf,
25        /// Underlying serde error.
26        #[source]
27        source: serde_json::Error,
28    },
29
30    /// Manifest validation failure (e.g. invalid name, bad `min_version`).
31    #[error("plugin invalid {path}: {message}")]
32    Invalid {
33        /// Path of the manifest.
34        path: PathBuf,
35        /// Human-readable problem description.
36        message: String,
37    },
38
39    /// Plugin `name` doesn't match the parent directory.
40    #[error(
41        "plugin name '{manifest_name}' does not match parent directory '{dir_name}' (at {path})"
42    )]
43    NameMismatch {
44        /// Name field in `plugin.json`.
45        manifest_name: String,
46        /// On-disk directory name.
47        dir_name: String,
48        /// Path of the manifest.
49        path: PathBuf,
50    },
51
52    /// Marketplace install rejected: marketplace not in the strict allowlist.
53    #[error("marketplace '{url}' is not in plugins.marketplaces.strict_known")]
54    UnknownMarketplace {
55        /// Offending URL.
56        url: String,
57    },
58
59    /// Marketplace install rejected: marketplace is in the block list.
60    #[error("marketplace '{url}' is in plugins.marketplaces.blocked")]
61    BlockedMarketplace {
62        /// Offending URL.
63        url: String,
64    },
65
66    /// Plugin not found in the marketplace index.
67    #[error("plugin '{name}' not found in marketplace '{url}'")]
68    PluginNotFound {
69        /// Plugin name requested.
70        name: String,
71        /// Marketplace URL.
72        url: String,
73    },
74
75    /// Sha256 mismatch between marketplace metadata and the downloaded tarball.
76    #[error("sha256 mismatch for '{name}' (expected {expected}, got {actual})")]
77    Sha256Mismatch {
78        /// Plugin name.
79        name: String,
80        /// Expected hex digest.
81        expected: String,
82        /// Computed hex digest.
83        actual: String,
84    },
85
86    /// Plugin disabled by `CALIBAN_STRICT_PLUGIN_ONLY_CUSTOMIZATION` policy.
87    #[error(
88        "plugin '{name}' is not managed-scope; strict-plugin-only-customization mode rejects it"
89    )]
90    StrictPluginOnly {
91        /// Plugin name.
92        name: String,
93    },
94
95    /// HTTP transport failure (marketplace fetch, tarball download).
96    #[error("http transport error: {0}")]
97    Http(#[from] reqwest::Error),
98
99    /// Url parse failure.
100    #[error("invalid url: {0}")]
101    Url(#[from] url::ParseError),
102
103    /// Tarball extraction failure.
104    #[error("extract: {0}")]
105    Extract(String),
106}