Skip to main content

helm_schema/
error.rs

1use std::path::PathBuf;
2
3/// Errors produced while loading charts, analyzing templates, and emitting schemas.
4#[derive(Debug, thiserror::Error)]
5pub enum CliError {
6    /// Virtual-filesystem operation failed.
7    #[error("vfs error: {0}")]
8    Vfs(#[from] vfs::VfsError),
9
10    /// Operating-system I/O operation failed.
11    #[error("io error: {0}")]
12    Io(#[from] std::io::Error),
13
14    /// YAML input could not be decoded.
15    #[error("yaml error: {0}")]
16    Yaml(#[from] serde_yaml::Error),
17
18    /// Values declarations use keys whose spelling Helm normalizes ambiguously.
19    #[error(
20        "unquoted YAML 1.1 Boolean-alias keys are not supported in chart declarations:\n{details}"
21    )]
22    YamlBooleanAliasKeys {
23        /// Deterministically ordered file locations and source spellings.
24        details: String,
25    },
26
27    /// A values declaration could not be structurally inspected for key style.
28    #[error("failed to inspect YAML Boolean-alias keys in {path}: {message}")]
29    YamlBooleanAliasScan {
30        /// Values declaration being inspected.
31        path: String,
32        /// YAML parser failure.
33        message: String,
34    },
35
36    /// Multiple dependency declarations target the same values root.
37    #[error(
38        "duplicate dependency values keys in {path}:\n{details}\neach dependency must own a unique .Values root"
39    )]
40    DuplicateDependencyValuesKeys {
41        /// Manifest containing the duplicate declarations.
42        path: String,
43        /// Deterministically ordered values keys and their declarations.
44        details: String,
45    },
46
47    /// Multiple vendored entries have the same internal chart name.
48    #[error(
49        "duplicate installed dependency names in {path}:\n{details}\nHelm's installed-entry association for duplicate internal names is nondeterministic"
50    )]
51    DuplicateInstalledDependencyNames {
52        /// Vendored charts directory containing the duplicate entries.
53        path: String,
54        /// Deterministically ordered internal names and entry paths.
55        details: String,
56    },
57
58    /// JSON input or output could not be decoded or encoded.
59    #[error("json error: {0}")]
60    Json(#[from] serde_json::Error),
61
62    /// A caller override is not a JSON Schema document root.
63    #[error("override schema root in {path} must be an object or boolean, found {kind}")]
64    InvalidOverrideRoot {
65        /// Override file carrying the invalid root.
66        path: PathBuf,
67        /// JSON kind found at the document root.
68        kind: &'static str,
69    },
70
71    /// A final output document is not a JSON Schema root.
72    #[error("final schema root must be an object or boolean, found {kind}")]
73    InvalidFinalSchemaRoot {
74        /// JSON kind found at the document root.
75        kind: &'static str,
76    },
77
78    /// Helm template source could not be parsed.
79    #[error("template parse error: {0}")]
80    TemplateParse(#[from] helm_schema_ast::ParseError),
81
82    /// Chart discovery found no analyzable charts.
83    #[error("no charts discovered")]
84    NoChartsDiscovered,
85
86    /// A discovered subchart path has no usable chart name.
87    #[error("subchart name missing for {path}")]
88    SubchartNameMissing {
89        /// Path of the unnamed subchart.
90        path: String,
91    },
92
93    /// An archive does not contain a chart manifest.
94    #[error("no Chart.yaml found in archive {archive}")]
95    NoChartYamlInArchive {
96        /// Path or identifier of the archive.
97        archive: String,
98    },
99
100    /// The output directory could not be created.
101    #[error("failed to create output directory {path}")]
102    CreateOutputDir {
103        /// Directory creation target.
104        path: PathBuf,
105        /// Underlying filesystem failure.
106        #[source]
107        source: std::io::Error,
108    },
109
110    /// A generated schema could not be written.
111    #[error("failed to write output {path}")]
112    WriteOutput {
113        /// Output file that could not be written.
114        path: PathBuf,
115        /// Underlying filesystem failure.
116        #[source]
117        source: std::io::Error,
118    },
119
120    /// Wraps any failure surfaced by the `jsonschema` / `referencing`
121    /// full-inlining pass: file-not-found, JSON parse error, malformed
122    /// URI, pointer-to-nowhere, missing anchor, etc. The wrapped variant
123    /// carries the structured cause so callers can pattern-match on the
124    /// underlying problem (e.g. `Unretrievable { uri, source }` vs
125    /// `PointerToNowhere { pointer }`) rather than parsing a string.
126    #[error("$ref resolution failed: {0}")]
127    Referencing(#[from] jsonschema::ReferencingError),
128
129    /// A self-contained schema could not be produced from external references.
130    #[error("$ref bundling failed: {0}")]
131    RefBundling(String),
132
133    /// A local filesystem path cannot be represented as a file URI.
134    #[error("filesystem path cannot be represented as a file URI: {path}")]
135    InvalidFileUriPath {
136        /// Filesystem path that could not be encoded.
137        path: PathBuf,
138    },
139
140    /// A file URI cannot be represented as a local filesystem path.
141    #[error("file URI cannot be represented as a local filesystem path: {uri}")]
142    InvalidFileUri {
143        /// File URI that could not be decoded.
144        uri: String,
145    },
146
147    /// One loaded document exceeded the configured byte budget.
148    #[error("load budget exceeded for {subject} (limit {limit_bytes} bytes)")]
149    LoadBudgetExceeded {
150        /// Document or archive member being loaded.
151        subject: String,
152        /// Maximum permitted byte count.
153        limit_bytes: usize,
154    },
155
156    /// An archive or directory exceeded the configured entry budget.
157    #[error("load budget exceeded for {subject} (limit {limit_entries} entries)")]
158    LoadEntryBudgetExceeded {
159        /// Archive or directory being enumerated.
160        subject: String,
161        /// Maximum permitted entry count.
162        limit_entries: usize,
163    },
164
165    /// An archive member would escape its extraction root.
166    #[error("unsafe archive entry path {entry_path} in {archive}")]
167    UnsafeArchiveEntryPath {
168        /// Archive containing the unsafe member.
169        archive: String,
170        /// Untrusted member path rejected by validation.
171        entry_path: String,
172    },
173
174    /// Mutually-exclusive CLI flags or otherwise-invalid combination
175    /// detected after `clap` parsing succeeded.
176    #[error("invalid CLI options: {0}")]
177    CliValidation(String),
178
179    /// An emission selection resolves to a contradictory knob matrix.
180    #[error("invalid emission policy: {0}")]
181    InvalidEmissionPolicy(#[from] helm_schema_gen::InvalidEmissionPolicy),
182
183    /// An explicit config path could not be read.
184    #[error("failed to read config {path}: {source}")]
185    ConfigRead {
186        /// Config file path.
187        path: PathBuf,
188        /// Underlying filesystem failure.
189        #[source]
190        source: std::io::Error,
191    },
192
193    /// A config document is malformed or contains unknown fields.
194    #[error("invalid config {path}: {source}")]
195    InvalidConfig {
196        /// Config file path or packaged-chart member label.
197        path: String,
198        /// YAML decoding failure.
199        #[source]
200        source: serde_yaml::Error,
201    },
202
203    /// A config document uses a version this binary cannot honor exactly.
204    #[error(
205        "unsupported config version {found} in {path}; supported range is {supported_min}..={supported_max}; update the config or the helm-schema binary"
206    )]
207    UnsupportedConfigVersion {
208        /// Config file path.
209        path: PathBuf,
210        /// Version requested by the config.
211        found: u64,
212        /// Oldest config version honored by this binary.
213        supported_min: u64,
214        /// Newest config version honored by this binary.
215        supported_max: u64,
216    },
217}
218
219/// Result returned by the schema engine's public operations.
220pub type EngineResult<T> = std::result::Result<T, CliError>;