rdf_fusion_execution/sparql/
error.rs

1use crate::sparql::SparqlSyntaxError;
2use datafusion::error::DataFusionError;
3use oxrdfio::RdfParseError;
4use rdf_fusion_model::StorageError;
5use rdf_fusion_model::{NamedNode, Term};
6use sparesults::QueryResultsParseError;
7use std::convert::Infallible;
8use std::error::Error;
9use std::io;
10
11/// A SPARQL evaluation error
12#[derive(Debug, thiserror::Error)]
13#[non_exhaustive]
14pub enum SparqlEvaluationError {
15    /// Error from the underlying RDF dataset
16    #[error(transparent)]
17    Dataset(Box<dyn Error + Send + Sync>),
18    /// Error during `SERVICE` evaluation
19    #[error("{0}")]
20    Service(#[source] Box<dyn Error + Send + Sync>),
21    /// Error if the dataset returns the default graph even if a named graph is expected
22    #[error(
23        "The SPARQL dataset returned the default graph even if a named graph is expected"
24    )]
25    UnexpectedDefaultGraph,
26    /// The variable storing the `SERVICE` name is unbound
27    #[error("The variable encoding the service name is unbound")]
28    UnboundService,
29    /// Invalid service name
30    #[error("{0} is not a valid service name")]
31    InvalidServiceName(Term),
32    /// The given `SERVICE` is not supported
33    #[error("The service {0} is not supported")]
34    UnsupportedService(NamedNode),
35    #[error("The storage provided a triple term that is not a valid RDF-star term")]
36    InvalidStorageTripleTerm,
37}
38
39impl From<Infallible> for SparqlEvaluationError {
40    #[inline]
41    fn from(error: Infallible) -> Self {
42        match error {}
43    }
44}
45
46/// A SPARQL evaluation error.
47#[derive(Debug, thiserror::Error)]
48#[non_exhaustive]
49pub enum QueryEvaluationError {
50    /// An error in SPARQL parsing.
51    #[error(transparent)]
52    Parsing(#[from] SparqlSyntaxError),
53    /// An error from the storage.
54    #[error(transparent)]
55    Storage(#[from] StorageError),
56    /// An error while parsing an external RDF file.
57    #[error(transparent)]
58    GraphParsing(#[from] RdfParseError),
59    /// An error while parsing an external result file (likely from a federated query).
60    #[error(transparent)]
61    ResultsParsing(#[from] QueryResultsParseError),
62    /// An error returned during results serialization.
63    #[error(transparent)]
64    ResultsSerialization(io::Error),
65    /// Error during `SERVICE` evaluation
66    #[error("{0}")]
67    Service(#[source] Box<dyn Error + Send + Sync + 'static>),
68    /// Error when `CREATE` tries to create an already existing graph
69    #[error("The graph {0} already exists")]
70    GraphAlreadyExists(NamedNode),
71    /// Error when `DROP` or `CLEAR` tries to remove a not existing graph
72    #[error("The graph {0} does not exist")]
73    GraphDoesNotExist(NamedNode),
74    /// The variable storing the `SERVICE` name is unbound
75    #[error("The variable encoding the service name is unbound")]
76    UnboundService,
77    /// The given `SERVICE` is not supported
78    #[error("The service {0} is not supported")]
79    UnsupportedService(NamedNode),
80    /// The given content media type returned from an HTTP response is not supported (`SERVICE` and `LOAD`)
81    #[error("The content media type {0} is not supported")]
82    UnsupportedContentType(String),
83    /// The `SERVICE` call has not returns solutions
84    #[error("The service is not returning solutions but a boolean or a graph")]
85    ServiceDoesNotReturnSolutions,
86    /// The results are not a RDF graph
87    #[error("The query results are not a RDF graph")]
88    NotAGraph,
89    #[error("An error returned from the query engine: {0}")]
90    Engine(DataFusionError),
91    #[error("A feature has not yet been implemented: {0}")]
92    NotImplemented(String),
93    #[error("An internal error that likely indicates towards a bug in RdfFusion: {0}")]
94    InternalError(String),
95}
96
97impl QueryEvaluationError {
98    pub fn internal<T>(cause: String) -> Result<T, Self> {
99        Err(QueryEvaluationError::InternalError(cause))
100    }
101}
102
103impl From<Infallible> for QueryEvaluationError {
104    #[inline]
105    fn from(error: Infallible) -> Self {
106        match error {}
107    }
108}
109
110impl From<SparqlEvaluationError> for QueryEvaluationError {
111    fn from(error: SparqlEvaluationError) -> Self {
112        match error {
113            SparqlEvaluationError::Dataset(error) => match error.downcast() {
114                Ok(error) => Self::Storage(*error),
115                Err(error) => Self::InternalError(error.to_string()),
116            },
117            SparqlEvaluationError::Service(error) => Self::Service(error),
118            #[allow(clippy::todo, reason = "Not production ready")]
119            _ => todo!("Integrate error"),
120        }
121    }
122}
123
124impl From<DataFusionError> for QueryEvaluationError {
125    fn from(error: DataFusionError) -> Self {
126        Self::Engine(error)
127    }
128}