Skip to main content

soldeer_core/
errors.rs

1use std::{
2    io,
3    path::{PathBuf, StripPrefixError},
4};
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8#[non_exhaustive]
9pub enum SoldeerError {
10    #[error("error during login: {0}")]
11    AuthError(#[from] AuthError),
12
13    #[error("error during config operation: {0}")]
14    ConfigError(#[from] ConfigError),
15
16    #[error("error during downloading ({dep}): {source}")]
17    DownloadError { dep: String, source: DownloadError },
18
19    #[error("error during install operation: {0}")]
20    InstallError(#[from] InstallError),
21
22    #[error("error during lockfile operation: {0}")]
23    LockError(#[from] LockError),
24
25    #[error("error during publishing: {0}")]
26    PublishError(#[from] PublishError),
27
28    #[error("error during remappings operation: {0}")]
29    RemappingsError(#[from] RemappingsError),
30
31    #[error("error during registry operation: {0}")]
32    RegistryError(#[from] RegistryError),
33
34    #[error("error during update operation: {0}")]
35    UpdateError(#[from] UpdateError),
36
37    #[error("error during IO operation: {0}")]
38    IOError(#[from] io::Error),
39}
40
41#[derive(Error, Debug)]
42#[non_exhaustive]
43pub enum AuthError {
44    #[error("login error: invalid email or password")]
45    InvalidCredentials,
46
47    #[error("login error: invalid token")]
48    InvalidToken,
49
50    #[error("missing token, run `soldeer login`")]
51    MissingToken,
52
53    #[error("error during IO operation for the security file: {0}")]
54    IOError(#[from] io::Error),
55
56    #[error("http error during login: {0}")]
57    HttpError(#[from] reqwest::Error),
58
59    #[error("TUI disabled and no credentials passed via CLI")]
60    TuiDisabled,
61}
62
63#[derive(Error, Debug)]
64#[non_exhaustive]
65pub enum ConfigError {
66    #[error("config file is not valid: {0}")]
67    Parsing(#[from] toml_edit::TomlError),
68
69    #[error("error writing to config file: {0}")]
70    FileWriteError(#[from] io::Error),
71
72    #[error("empty `version` field in {0}")]
73    EmptyVersion(String),
74
75    #[error("missing `{field}` field in {dep}")]
76    MissingField { field: String, dep: String },
77
78    #[error("invalid `{field}` field in {dep}")]
79    InvalidField { field: String, dep: String },
80
81    #[error("field `{field}` conflicts with `{conflicts_with}` in {dep}")]
82    FieldConflict { field: String, conflicts_with: String, dep: String },
83
84    #[error("only one of `rev`, `branch` or `tag` can be specified for git dependency {0}")]
85    GitIdentifierConflict(String),
86
87    #[error("dependency {0} is not valid")]
88    InvalidDependency(String),
89
90    #[error("dependency {0} was not found")]
91    MissingDependency(String),
92
93    #[error("error parsing config file: {0}")]
94    DeserializeError(#[from] toml_edit::de::Error),
95
96    #[error("error generating config file: {0}")]
97    SerializeError(#[from] toml_edit::ser::Error),
98
99    #[error("error during config operation: {0}")]
100    DownloadError(#[from] DownloadError),
101
102    #[error(
103        "the version requirement string for {0} cannot contain the equal symbol for git dependencies and http dependencies with a custom URL"
104    )]
105    InvalidVersionReq(String),
106
107    #[error("dependency specifier {0} cannot be parsed as name~version")]
108    InvalidNameAndVersion(String),
109
110    #[error("invalid project root path in {dep_path}: {project_root}")]
111    InvalidProjectRoot { project_root: PathBuf, dep_path: PathBuf },
112}
113
114#[derive(Error, Debug)]
115#[non_exhaustive]
116pub enum DownloadError {
117    #[error("error downloading dependency: {0}")]
118    HttpError(#[from] reqwest::Error),
119
120    #[error("error extracting dependency: {0}")]
121    UnzipError(#[from] zip_extract::ZipExtractError),
122
123    #[error("error during git command {args:?}: {message}")]
124    GitError { message: String, args: Vec<String> },
125
126    #[error("error during IO operation for {path:?}: {source}")]
127    IOError { path: PathBuf, source: io::Error },
128
129    #[error("error during async operation: {0}")]
130    AsyncError(#[from] tokio::task::JoinError),
131
132    #[error("could download the dependencies of this dependency {0}")]
133    SubdependencyError(String),
134
135    #[error("the provided URL is invalid: {0}")]
136    InvalidUrl(String),
137
138    #[error("error during registry operation: {0}")]
139    RegistryError(#[from] RegistryError),
140
141    #[error("dependency not found: {0}")]
142    DependencyNotFound(String),
143}
144
145#[derive(Error, Debug)]
146#[non_exhaustive]
147pub enum InstallError {
148    #[error("zip checksum for {path} does not match lock file: expected {expected}, got {actual}")]
149    ZipIntegrityError { path: PathBuf, expected: String, actual: String },
150
151    #[error("error during IO operation for {path:?}: {source}")]
152    IOError { path: PathBuf, source: io::Error },
153
154    #[error("error during git command: {0}")]
155    GitError(String),
156
157    #[error("error during dependency installation: {0}")]
158    DownloadError(#[from] DownloadError),
159
160    #[error("error during dependency installation: {0}")]
161    ConfigError(#[from] ConfigError),
162
163    #[error("error during async operation: {0}")]
164    AsyncError(#[from] tokio::task::JoinError),
165
166    #[error("error during forge command: {0}")]
167    ForgeError(String),
168
169    #[error("error during registry operation: {0}")]
170    RegistryError(#[from] RegistryError),
171
172    #[error("error with lockfile: {0}")]
173    LockError(#[from] LockError),
174}
175
176#[derive(Error, Debug)]
177#[non_exhaustive]
178pub enum LockError {
179    #[error("soldeer.lock is missing")]
180    Missing,
181
182    #[error("dependency {0} is already installed")]
183    DependencyInstalled(String),
184
185    #[error("IO error for soldeer.lock: {0}")]
186    IOError(#[from] io::Error),
187
188    #[error("error generating soldeer.lock contents: {0}")]
189    SerializeError(#[from] toml_edit::ser::Error),
190
191    #[error("lock entry does not match a valid format")]
192    InvalidLockEntry,
193
194    #[error("missing `{field}` field in lock entry for {dep}")]
195    MissingField { field: String, dep: String },
196
197    #[error("foundry.lock is missing")]
198    FoundryLockMissing,
199
200    #[error("error parsing lockfile contents: {0}")]
201    DeserializeError(#[from] serde_json::Error),
202}
203
204#[derive(Error, Debug)]
205#[non_exhaustive]
206pub enum PublishError {
207    #[error("no files to publish")]
208    NoFiles,
209
210    #[error("error during zipping: {0}")]
211    ZipError(#[from] zip::result::ZipError),
212
213    #[error("error during IO operation for {path:?}: {source}")]
214    IOError { path: PathBuf, source: io::Error },
215
216    #[error("error while computing the relative path: {0}")]
217    RelativePathError(#[from] StripPrefixError),
218
219    #[error("auth error: {0}")]
220    AuthError(#[from] AuthError),
221
222    #[error("registry error during publishing: {0}")]
223    DownloadError(#[from] RegistryError),
224
225    #[error(
226        "Project not found. Make sure you send the right dependency name. The dependency name is the project name you created on https://soldeer.xyz"
227    )]
228    ProjectNotFound,
229
230    #[error("dependency already exists")]
231    AlreadyExists,
232
233    #[error("the package is too big (over 50 MB)")]
234    PayloadTooLarge,
235
236    #[error("http error during publishing: {0}")]
237    HttpError(#[from] reqwest::Error),
238
239    #[error(
240        "invalid package name, only alphanumeric characters, `-` and `@` are allowed. Length must be between 3 and 100 characters"
241    )]
242    InvalidName,
243
244    #[error("package version cannot be empty")]
245    EmptyVersion,
246
247    #[error("user cancelled operation")]
248    UserAborted,
249
250    #[error("unknown http error")]
251    UnknownError,
252}
253
254#[derive(Error, Debug)]
255#[non_exhaustive]
256pub enum RegistryError {
257    #[error("error with registry request: {0}")]
258    HttpError(#[from] reqwest::Error),
259
260    #[error("could not get the dependency URL for {0}")]
261    URLNotFound(String),
262
263    #[error(
264        "project {0} not found. Private projects require to log in before install. Please check the dependency name (project name) or create a new project on https://soldeer.xyz"
265    )]
266    ProjectNotFound(String),
267
268    #[error("auth error: {0}")]
269    AuthError(#[from] AuthError),
270
271    #[error("package {0} has no version")]
272    NoVersion(String),
273
274    #[error("no matching version found for {dependency} with version requirement {version_req}")]
275    NoMatchingVersion { dependency: String, version_req: String },
276}
277
278#[derive(Error, Debug)]
279#[non_exhaustive]
280pub enum RemappingsError {
281    #[error("error writing to remappings file: {0}")]
282    FileWriteError(#[from] io::Error),
283
284    #[error("error while interacting with the config file: {0}")]
285    ConfigError(#[from] ConfigError),
286
287    #[error("dependency not found: {0}")]
288    DependencyNotFound(String),
289}
290
291#[derive(Error, Debug)]
292#[non_exhaustive]
293pub enum UpdateError {
294    #[error("registry error: {0}")]
295    RegistryError(#[from] RegistryError),
296
297    #[error("download error: {0}")]
298    DownloadError(#[from] DownloadError),
299
300    #[error("error during install operation: {0}")]
301    InstallError(#[from] InstallError),
302
303    #[error("error during async operation: {0}")]
304    AsyncError(#[from] tokio::task::JoinError),
305}