Skip to main content

frm/
errors.rs

1// Copyright (c) 2025-2026 Michael S. Klishin and Contributors
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::io;
10
11use bel7_cli::{ExitCode, ExitCodeProvider};
12use thiserror::Error;
13
14use rabbitmq_versioning::Version;
15
16#[derive(Error, Debug)]
17pub enum Error {
18    #[error("version {0} is not installed")]
19    VersionNotInstalled(Version),
20
21    #[error("version {0} is already installed")]
22    VersionAlreadyInstalled(Version),
23
24    #[error("invalid version format: {0}")]
25    InvalidVersion(String),
26
27    #[error("download failed: {0}")]
28    DownloadFailed(String),
29
30    #[error("release not found: {0}")]
31    ReleaseNotFound(String),
32
33    #[error("extraction failed: {0}")]
34    ExtractionFailed(String),
35
36    #[error("configuration error: {0}")]
37    Config(String),
38
39    #[error("unknown tool: {0}")]
40    UnknownTool(String),
41
42    #[error("unknown config file: {0}")]
43    UnknownConfigFile(String),
44
45    #[error("file not found: {0}")]
46    FileNotFound(String),
47
48    #[error("command failed: {0}")]
49    CommandFailed(String),
50
51    #[error("I/O error: {0}")]
52    Io(#[from] io::Error),
53
54    #[error("HTTP error: {0}")]
55    Http(#[from] reqwest::Error),
56
57    #[error("TOML parse error: {0}")]
58    TomlParse(#[from] toml::de::Error),
59
60    #[error("TOML serialization error: {0}")]
61    TomlSerialize(#[from] toml::ser::Error),
62
63    #[error("JSON error: {0}")]
64    Json(#[from] serde_json::Error),
65
66    #[error("expected an alpha version, got: {0}")]
67    ExpectedAlphaVersion(Version),
68
69    #[error("expected a non-alpha version, got: {0}")]
70    ExpectedNonAlphaVersion(Version),
71
72    #[error("this command only supports release versions")]
73    AlphaVersionNotSupported,
74
75    #[error("this command only supports alpha versions")]
76    ReleaseVersionNotSupported,
77
78    #[error("no alpha releases found")]
79    NoAlphaReleasesFound,
80
81    #[error("no GA versions installed (use 'frm releases install' first)")]
82    NoGAVersionsInstalled,
83
84    #[error("no alpha versions installed (use 'frm alphas install latest' first)")]
85    NoAlphaVersionsInstalled,
86
87    #[error("invalid date/time: {0}")]
88    InvalidDateTime(String),
89
90    #[error("version mismatch: expected {expected}, detected {detected} in tarball filename")]
91    TanzuVersionMismatch {
92        expected: Version,
93        detected: Version,
94    },
95
96    #[error("signature verification failed: {0}")]
97    SignatureVerificationFailed(String),
98}
99
100impl ExitCodeProvider for Error {
101    fn exit_code(&self) -> ExitCode {
102        match self {
103            Error::VersionNotInstalled(_) => ExitCode::NoInput,
104            Error::VersionAlreadyInstalled(_) => ExitCode::CantCreat,
105            Error::InvalidVersion(_) => ExitCode::Usage,
106            Error::DownloadFailed(_) => ExitCode::Unavailable,
107            Error::ReleaseNotFound(_) => ExitCode::NoInput,
108            Error::ExtractionFailed(_) => ExitCode::Software,
109            Error::Config(_) => ExitCode::Config,
110            Error::UnknownTool(_) => ExitCode::Usage,
111            Error::UnknownConfigFile(_) => ExitCode::Usage,
112            Error::FileNotFound(_) => ExitCode::NoInput,
113            Error::CommandFailed(_) => ExitCode::Software,
114            Error::Io(_) => ExitCode::IoErr,
115            Error::Http(_) => ExitCode::Protocol,
116            Error::TomlParse(_) => ExitCode::DataErr,
117            Error::TomlSerialize(_) => ExitCode::Software,
118            Error::Json(_) => ExitCode::DataErr,
119            Error::ExpectedAlphaVersion(_) => ExitCode::Usage,
120            Error::ExpectedNonAlphaVersion(_) => ExitCode::Usage,
121            Error::AlphaVersionNotSupported => ExitCode::Usage,
122            Error::ReleaseVersionNotSupported => ExitCode::Usage,
123            Error::NoAlphaReleasesFound => ExitCode::NoInput,
124            Error::NoGAVersionsInstalled => ExitCode::NoInput,
125            Error::NoAlphaVersionsInstalled => ExitCode::NoInput,
126            Error::InvalidDateTime(_) => ExitCode::Usage,
127            Error::TanzuVersionMismatch { .. } => ExitCode::DataErr,
128            Error::SignatureVerificationFailed(_) => ExitCode::DataErr,
129        }
130    }
131}
132
133impl From<rabbitmq_versioning::Error> for Error {
134    fn from(e: rabbitmq_versioning::Error) -> Self {
135        match e {
136            rabbitmq_versioning::Error::InvalidVersion(s) => Error::InvalidVersion(s),
137            rabbitmq_versioning::Error::InvalidPrerelease(s) => Error::InvalidVersion(s),
138        }
139    }
140}