Skip to main content

asimov_installer/installer/
error.rs

1// This is free and unencumbered software released into the public domain.
2
3use super::platform::PlatformInfo;
4use asimov_registry::error as registry;
5use std::{
6    boxed::Box,
7    io,
8    path::PathBuf,
9    string::{String, ToString as _},
10};
11use thiserror::Error;
12
13#[derive(Debug, Error)]
14pub enum InstallError {
15    #[error(transparent)]
16    WorkDir(#[from] WorkDirError),
17    #[error(transparent)]
18    Preinstall(#[from] PreinstallError),
19    #[error(transparent)]
20    Finish(#[from] FinishInstallError),
21}
22
23#[derive(Debug, Error)]
24pub enum UpgradeError {
25    #[error("upgrade publication or recovery failed: {0}")]
26    Publication(#[from] io::Error),
27    #[error("failed to check the latest version of module: {0}")]
28    Fetch(#[from] FetchError),
29    #[error("unable to read current version of module: {0}")]
30    CheckVersion(#[from] registry::ModuleVersionError),
31    #[error(transparent)]
32    WorkDir(#[from] WorkDirError),
33    #[error("unable to check if module is enabled: {0}")]
34    CheckEnabled(#[from] registry::IsModuleEnabledError),
35    #[error(transparent)]
36    Preinstall(#[from] PreinstallError),
37    #[error(transparent)]
38    Uninstall(#[from] UninstallError),
39    #[error(transparent)]
40    Install(#[from] FinishInstallError),
41    #[error("failed to re-enable module: {0}")]
42    ReEnable(#[from] registry::EnableError),
43}
44
45#[derive(Debug, Error)]
46pub enum UninstallError {
47    #[error("uninstall publication or recovery failed: {0}")]
48    Publication(#[from] io::Error),
49    #[error("unable to read module manifest file: {0}")]
50    Read(#[from] registry::ManifestError),
51    #[error(transparent)]
52    Disable(#[from] registry::DisableError),
53    #[error("unable to remove installed module binary `{0}`: {1}")]
54    RemoveBinary(String, #[source] registry::RemoveBinaryError),
55    #[error("unable to remove installed module: {0}")]
56    RemoveModule(#[from] registry::RemoveModuleError),
57}
58
59mod common {
60    use super::*;
61
62    #[derive(Debug, Error)]
63    pub enum FetchError {
64        #[error(transparent)]
65        Http(#[from] HttpError),
66        #[error("unable to deserialize GitHub API response: {0}")]
67        Deserialize(#[from] DeserializeError),
68    }
69
70    impl From<reqwest::Error> for FetchError {
71        fn from(value: reqwest::Error) -> Self {
72            FetchError::Http(HttpError::Http(value))
73        }
74    }
75
76    #[derive(Debug, Error)]
77    pub enum DeserializeError {
78        #[error("JSON deserialization failed: {0}")]
79        Json(#[from] serde_json::Error),
80        #[error("YAML deserialization failed: {0}")]
81        Yaml(#[from] serde_yaml_ng::Error),
82    }
83
84    #[derive(Debug, Error)]
85    pub enum FetchChecksumError {
86        #[error(transparent)]
87        Http(#[from] HttpError),
88    }
89
90    impl From<reqwest::Error> for FetchChecksumError {
91        fn from(value: reqwest::Error) -> Self {
92            FetchChecksumError::Http(HttpError::Http(value))
93        }
94    }
95
96    #[derive(Debug, Error)]
97    pub enum VerifyChecksumError {
98        #[error("failed to read target file: {0}")]
99        Io(#[from] io::Error),
100        #[error("invalid checksum `{0}`, expected `{1}`")]
101        InvalidChecksum(String, String),
102    }
103
104    #[derive(Debug, Error)]
105    pub enum DownloadError {
106        #[error(transparent)]
107        Http(#[from] HttpError),
108        #[error("failed to write data on disk: {0}")]
109        Io(#[from] io::Error),
110        #[error("no matching asset found")]
111        NoMatch,
112    }
113
114    impl From<reqwest::Error> for DownloadError {
115        fn from(value: reqwest::Error) -> Self {
116            DownloadError::Http(HttpError::Http(value))
117        }
118    }
119
120    #[derive(Debug, Error)]
121    pub enum HttpError {
122        #[error("HTTP request failed: {0}")]
123        Http(#[from] reqwest::Error),
124        /// Shared proxy discovery or target-origin validation failed.
125        #[error(transparent)]
126        Proxy(#[from] asimov_http::proxy::Error),
127        /// The redirect chain exceeded its limit or contained an invalid hop.
128        #[error("HTTP redirect failed: {0}")]
129        Redirect(&'static str),
130        #[error("HTTP status code was not successful: {0}")]
131        NotSuccess(reqwest::StatusCode),
132    }
133
134    #[derive(Debug, Error)]
135    pub enum PreinstallError {
136        #[error(transparent)]
137        InvalidModuleName(asimov_module::InvalidModuleName),
138        #[error("invalid name for a required module: {0}")]
139        InvalidDependencyName(asimov_module::InvalidModuleName),
140
141        #[error("failed fetch release: {0}")]
142        FetchRelease(FetchError),
143
144        #[error("no binaries available for platform `{}-{}{}`", .0.os, .0.arch, if let Some(ref libc) = .0.libc { "-".to_string() + libc } else { "".to_string() })]
145        NotAvailable(PlatformInfo),
146
147        #[error(transparent)]
148        Download(#[from] DownloadError),
149        #[error("failed to fetch module manifest: {0}")]
150        FetchManifest(FetchError),
151
152        #[error("failed to install dependency module `{0}`: {1}")]
153        Dependency(String, Box<InstallError>),
154
155        #[error("failed to fetch checksum: {0}")]
156        FetchChecksum(#[from] FetchChecksumError),
157        #[error(transparent)]
158        VerifyChecksum(#[from] VerifyChecksumError),
159
160        #[error("failed to create directory for extracting: {0}")]
161        CreateExtractDir(io::Error),
162
163        #[error("failed to extract archive: {0}")]
164        Extract(io::Error),
165
166        #[error("module manifest does not have a choice of model size `{0}`")]
167        NoSuchModel(String),
168
169        #[error("error while installing required model: {0}")]
170        InstallModel(#[from] asimov_huggingface::HuggingfaceError),
171    }
172
173    #[derive(Debug, Error)]
174    pub enum WorkDirError {
175        #[error("failed to create the module file tree: {0}")]
176        CreateFileTree(#[source] registry::CreateFileTreeError),
177        #[error("failed to create directory for installing: {0}")]
178        CreateDir(#[source] io::Error),
179    }
180
181    #[derive(Debug, Error)]
182    pub enum FinishInstallError {
183        #[error("failed to create directory `{0}`: {1}")]
184        CreateDir(PathBuf, #[source] io::Error),
185        #[error("failed to write `{0}`: {1}")]
186        WriteFile(PathBuf, #[source] io::Error),
187        #[error("failed to move binary `{0}` into place: {1}")]
188        MoveBinary(String, #[source] io::Error),
189        #[cfg(unix)]
190        #[error("failed to set permissions: {0}")]
191        SetPermissions(#[source] io::Error),
192        #[error("failed to serialize module manifest: {0}")]
193        Serialize(#[source] serde_json::Error),
194        #[error("failed to install module: {0}")]
195        AddModule(#[from] registry::AddModuleError),
196    }
197}
198pub use common::*;