Skip to main content

converge_storage/
error.rs

1// Copyright 2024-2026 Reflective Labs
2// SPDX-License-Identifier: MIT
3
4use std::path::PathBuf;
5
6#[derive(Debug, thiserror::Error)]
7pub enum StorageError {
8    #[error("unsupported storage scheme: {0}")]
9    UnsupportedScheme(String),
10
11    #[error("invalid storage URI: {0}")]
12    InvalidUri(String),
13
14    #[error("local path does not exist: {}", .0.display())]
15    LocalPathNotFound(PathBuf),
16
17    #[error("object store error: {0}")]
18    ObjectStore(#[from] object_store::Error),
19
20    #[error("configuration error: {0}")]
21    Config(String),
22}
23
24#[cfg(test)]
25mod tests {
26    use super::*;
27
28    #[test]
29    fn display_unsupported_scheme() {
30        let err = StorageError::UnsupportedScheme("ftp".into());
31        assert_eq!(err.to_string(), "unsupported storage scheme: ftp");
32    }
33
34    #[test]
35    fn display_invalid_uri() {
36        let err = StorageError::InvalidUri("not://valid".into());
37        assert_eq!(err.to_string(), "invalid storage URI: not://valid");
38    }
39
40    #[test]
41    fn display_local_path_not_found() {
42        let err = StorageError::LocalPathNotFound(PathBuf::from("/missing/dir"));
43        assert_eq!(err.to_string(), "local path does not exist: /missing/dir");
44    }
45
46    #[test]
47    fn display_config() {
48        let err = StorageError::Config("bad value".into());
49        assert_eq!(err.to_string(), "configuration error: bad value");
50    }
51
52    #[test]
53    fn from_object_store_error() {
54        let obj_err = object_store::Error::Generic {
55            store: "test",
56            source: "boom".into(),
57        };
58        let err: StorageError = obj_err.into();
59        assert!(matches!(err, StorageError::ObjectStore(_)));
60        assert!(err.to_string().contains("object store error"));
61    }
62
63    #[test]
64    fn error_trait_source_for_object_store_variant() {
65        use std::error::Error;
66
67        let obj_err = object_store::Error::Generic {
68            store: "test",
69            source: "inner".into(),
70        };
71        let err = StorageError::ObjectStore(obj_err);
72        assert!(err.source().is_some());
73    }
74
75    #[test]
76    fn error_trait_source_is_none_for_plain_variants() {
77        use std::error::Error;
78
79        assert!(
80            StorageError::UnsupportedScheme("x".into())
81                .source()
82                .is_none()
83        );
84        assert!(StorageError::InvalidUri("x".into()).source().is_none());
85        assert!(
86            StorageError::LocalPathNotFound(PathBuf::from("/x"))
87                .source()
88                .is_none()
89        );
90        assert!(StorageError::Config("x".into()).source().is_none());
91    }
92}