Skip to main content

boundless_market/storage/
error.rs

1// Copyright 2026 Boundless Foundation, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Error types for the storage module.
16
17use std::error::Error as StdError;
18
19/// Unified error type for storage operations.
20#[derive(thiserror::Error, Debug)]
21#[non_exhaustive]
22pub enum StorageError {
23    /// Unsupported URI scheme.
24    #[error("unsupported URI scheme: {0}")]
25    UnsupportedScheme(String),
26
27    /// Invalid URL.
28    #[error("invalid URL: {0}")]
29    InvalidUrl(&'static str),
30
31    /// URL parse error.
32    #[error("URL parse error: {0}")]
33    UrlParse(#[from] url::ParseError),
34
35    /// Resource size exceeds maximum allowed size.
36    #[error("size limit exceeded: {size} bytes (limit: {limit} bytes)")]
37    SizeLimitExceeded {
38        /// Actual size of the resource.
39        size: usize,
40        /// Maximum allowed size.
41        limit: usize,
42    },
43
44    /// IO error.
45    #[error("IO error: {0}")]
46    Io(#[from] std::io::Error),
47
48    /// HTTP error.
49    #[error("HTTP error: {0}")]
50    Http(#[source] Box<dyn StdError + Send + Sync + 'static>),
51
52    /// HTTP request failed with non-success status.
53    #[error("HTTP request failed with status: {0}")]
54    HttpStatus(u16),
55
56    /// S3 error.
57    #[cfg(feature = "s3")]
58    #[error("S3 error: {0}")]
59    S3(#[source] Box<dyn StdError + Send + Sync + 'static>),
60
61    /// Google Cloud Storage error.
62    #[cfg(feature = "gcs")]
63    #[error("GCS error: {0}")]
64    Gcs(#[source] Box<dyn StdError + Send + Sync + 'static>),
65
66    /// Environment variable error.
67    #[error("environment variable error: {0}")]
68    EnvVar(#[from] std::env::VarError),
69
70    /// Missing configuration parameter.
71    #[error("missing config parameter: {0}")]
72    MissingConfig(&'static str),
73
74    /// No storage uploader configured.
75    #[error("no storage uploader configured")]
76    NoUploader,
77
78    /// Other error.
79    #[error("{0}")]
80    Other(#[from] anyhow::Error),
81}
82
83impl StorageError {
84    /// Create an HTTP error from a reqwest error.
85    pub fn http(err: impl Into<Box<dyn StdError + Send + Sync + 'static>>) -> Self {
86        Self::Http(err.into())
87    }
88
89    /// Create an S3 error.
90    #[cfg(feature = "s3")]
91    pub fn s3(err: impl Into<Box<dyn StdError + Send + Sync + 'static>>) -> Self {
92        Self::S3(err.into())
93    }
94
95    /// Create a GCS error.
96    #[cfg(feature = "gcs")]
97    pub fn gcs(err: impl Into<Box<dyn StdError + Send + Sync + 'static>>) -> Self {
98        Self::Gcs(err.into())
99    }
100}