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}