zlayer_toolchain/error.rs
1//! Error types for the toolchain provisioning subsystem.
2//!
3//! The variant names (`RegistryError`, `CacheError`, `IoError`) mirror the
4//! subset of `zlayer_builder::error::BuildError` this crate bridges to via a
5//! `From` impl in the builder, so toolchain-provisioning errors (source build +
6//! prebuilt fetch) flow back through `?` at the builder call sites unchanged.
7
8use thiserror::Error;
9
10/// Errors raised while resolving or installing a runtime toolchain.
11#[derive(Debug, Error)]
12pub enum ToolchainError {
13 /// Registry / download / resolution failure (Homebrew API, GHCR blob pull,
14 /// `RepoSources` discovery, archive extraction, …). Also covers
15 /// toolchain-artifact registry operations: publishing a built toolchain to
16 /// an OCI registry and pulling one back down.
17 #[error("Registry error: {message}")]
18 RegistryError {
19 /// Underlying registry error description.
20 message: String,
21 },
22
23 /// Cache or config-serialisation failure.
24 #[error("Cache error: {message}")]
25 CacheError {
26 /// Underlying cache error description.
27 message: String,
28 },
29
30 /// A downloaded artifact's sha256 did not match the expected digest (either
31 /// a formula `urls.stable.checksum`, an upstream-published digest, or a
32 /// lockfile pin). The partial download is deleted before this is returned.
33 #[error("digest mismatch for {tool}: expected {expected}, got {actual}")]
34 DigestMismatch {
35 /// The tool / artifact whose digest failed to verify.
36 tool: String,
37 /// The expected sha256 (bare lowercase hex).
38 expected: String,
39 /// The sha256 actually computed over the downloaded bytes.
40 actual: String,
41 },
42
43 /// A containerized build step was required but no runtime executor has
44 /// been registered. Toolchain builds must NEVER fall back to a host
45 /// subprocess, so this is a hard error rather than a degraded path.
46 #[error("no container build executor registered; cannot build toolchain '{tool}' in isolation (register one via zlayer_toolchain::executor::set_container_executor)")]
47 ExecutorUnavailable {
48 /// The tool whose containerized build could not be executed.
49 tool: String,
50 },
51
52 /// A build recipe uses constructs this crate's recipe interpreter does not
53 /// support, so the toolchain cannot be built from it.
54 #[error("recipe for toolchain '{tool}' uses unsupported constructs: {}", constructs.join(", "))]
55 RecipeUnsupported {
56 /// The tool whose recipe could not be interpreted.
57 tool: String,
58 /// The unsupported recipe constructs that were encountered.
59 constructs: Vec<String>,
60 },
61
62 /// Underlying I/O error.
63 #[error("IO error: {0}")]
64 IoError(#[from] std::io::Error),
65}
66
67/// Result alias for toolchain operations.
68pub type Result<T, E = ToolchainError> = std::result::Result<T, E>;