Skip to main content

oxigraph/storage/
error.rs

1use crate::io::{RdfFormat, RdfParseError};
2use oxiri::IriParseError;
3use std::error::Error;
4use std::io;
5
6/// An error related to storage operations (reads, writes...).
7#[derive(Debug, thiserror::Error)]
8#[non_exhaustive]
9pub enum StorageError {
10    /// Error from the OS I/O layer.
11    #[error(transparent)]
12    Io(#[from] io::Error),
13    /// Error related to data corruption.
14    #[error(transparent)]
15    Corruption(#[from] CorruptionError),
16    #[doc(hidden)]
17    #[error("{0}")]
18    Other(#[source] Box<dyn Error + Send + Sync + 'static>),
19}
20
21impl From<StorageError> for io::Error {
22    #[inline]
23    fn from(error: StorageError) -> Self {
24        match error {
25            StorageError::Io(error) => error,
26            StorageError::Corruption(error) => error.into(),
27            StorageError::Other(error) => Self::other(error),
28        }
29    }
30}
31
32/// An error return if some content in the database is corrupted.
33#[derive(Debug, thiserror::Error)]
34#[error(transparent)]
35pub struct CorruptionError(#[from] CorruptionErrorKind);
36
37/// An error return if some content in the database is corrupted.
38#[derive(Debug, thiserror::Error)]
39enum CorruptionErrorKind {
40    #[error("{0}")]
41    Msg(String),
42    #[error("{0}")]
43    Other(#[source] Box<dyn Error + Send + Sync + 'static>),
44}
45
46impl CorruptionError {
47    /// Builds an error from a printable error message.
48    #[inline]
49    pub(crate) fn new(error: impl Into<Box<dyn Error + Send + Sync + 'static>>) -> Self {
50        Self(CorruptionErrorKind::Other(error.into()))
51    }
52
53    #[inline]
54    #[cfg(all(not(target_family = "wasm"), feature = "rocksdb"))]
55    pub(crate) fn from_missing_column_family_name(name: &'static str) -> Self {
56        // TODO: eventually use a dedicated error enum value
57        Self::msg(format!("Column family {name} does not exist"))
58    }
59
60    /// Builds an error from a printable error message.
61    #[inline]
62    pub(crate) fn msg(msg: impl Into<String>) -> Self {
63        Self(CorruptionErrorKind::Msg(msg.into()))
64    }
65}
66
67impl From<CorruptionError> for io::Error {
68    #[inline]
69    fn from(error: CorruptionError) -> Self {
70        Self::new(io::ErrorKind::InvalidData, error)
71    }
72}
73
74/// An error raised while loading a file into a [`Store`](crate::store::Store).
75#[derive(Debug, thiserror::Error)]
76pub enum LoaderError {
77    /// An error raised while reading the file.
78    #[error(transparent)]
79    Parsing(#[from] RdfParseError),
80    /// An error raised during the insertion in the store.
81    #[error(transparent)]
82    Storage(#[from] StorageError),
83    /// The base IRI is invalid.
84    #[error("Invalid base IRI '{iri}': {error}")]
85    InvalidBaseIri {
86        /// The IRI itself.
87        iri: String,
88        /// The parsing error.
89        #[source]
90        error: IriParseError,
91    },
92}
93
94impl From<LoaderError> for io::Error {
95    #[inline]
96    fn from(error: LoaderError) -> Self {
97        match error {
98            LoaderError::Storage(error) => error.into(),
99            LoaderError::Parsing(error) => error.into(),
100            LoaderError::InvalidBaseIri { .. } => {
101                Self::new(io::ErrorKind::InvalidInput, error.to_string())
102            }
103        }
104    }
105}
106
107/// An error raised while writing a file from a [`Store`](crate::store::Store).
108#[derive(Debug, thiserror::Error)]
109pub enum SerializerError {
110    /// An error raised while writing the content.
111    #[error(transparent)]
112    Io(#[from] io::Error),
113    /// An error raised during the lookup in the store.
114    #[error(transparent)]
115    Storage(#[from] StorageError),
116    /// A format compatible with [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset) is required.
117    #[error("A RDF format supporting datasets was expected, {0} found")]
118    DatasetFormatExpected(RdfFormat),
119}
120
121impl From<SerializerError> for io::Error {
122    #[inline]
123    fn from(error: SerializerError) -> Self {
124        match error {
125            SerializerError::Storage(error) => error.into(),
126            SerializerError::Io(error) => error,
127            SerializerError::DatasetFormatExpected(_) => {
128                Self::new(io::ErrorKind::InvalidInput, error.to_string())
129            }
130        }
131    }
132}