Skip to main content

public_traits/
errors.rs

1// Copyright 2016-2018 Mozilla
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4// this file except in compliance with the License. You may obtain a copy of the
5// License at http://www.apache.org/licenses/LICENSE-2.0
6// Unless required by applicable law or agreed to in writing, software distributed
7// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
8// CONDITIONS OF ANY KIND, either express or implied. See the License for the
9// specific language governing permissions and limitations under the License.
10
11#![allow(dead_code)]
12
13use std; // To refer to std::result::Result.
14
15use std::collections::BTreeSet;
16use std::error::Error;
17
18use thiserror::Error;
19
20use rusqlite;
21use uuid;
22
23use edn;
24
25use core_traits::{Attribute, ValueType};
26
27use db_traits::errors::DbError;
28use query_algebrizer_traits::errors::AlgebrizerError;
29use query_projector_traits::errors::ProjectorError;
30use query_pull_traits::errors::PullError;
31use sql_traits::errors::SQLError;
32
33pub type Result<T> = std::result::Result<T, MentatError>;
34
35#[derive(Debug, Error)]
36pub enum MentatError {
37    #[error("bad uuid {0}")]
38    BadUuid(String),
39
40    #[error("path {0} already exists")]
41    PathAlreadyExists(String),
42
43    #[error("variables {0:?} unbound at query execution time")]
44    UnboundVariables(BTreeSet<String>),
45
46    #[error("invalid argument name: '{0}'")]
47    InvalidArgumentName(String),
48
49    /// Bad JSON query options (`mentat::options_from_json`).
50    #[error("query options: {0}")]
51    BadQueryOptions(String),
52
53    #[error("unknown attribute: '{0}'")]
54    UnknownAttribute(String),
55
56    #[error("invalid vocabulary version")]
57    InvalidVocabularyVersion,
58
59    #[error(
60        "vocabulary {0}/version {1} already has attribute {2}, and the requested definition differs"
61    )]
62    ConflictingAttributeDefinitions(String, u32, String, Attribute, Attribute),
63
64    #[error("existing vocabulary {0} too new: wanted version {1}, got version {2}")]
65    ExistingVocabularyTooNew(String, u32, u32),
66
67    #[error("core schema: wanted version {0}, got version {1:?}")]
68    UnexpectedCoreSchema(u32, Option<u32>),
69
70    #[error("Lost the transact() race!")]
71    UnexpectedLostTransactRace,
72
73    #[error("missing core attribute {0}")]
74    MissingCoreVocabulary(edn::query::Keyword),
75
76    #[error("schema changed since query was prepared")]
77    PreparedQuerySchemaMismatch,
78
79    #[error("provided value of type {0} doesn't match attribute value type {1}")]
80    ValueTypeMismatch(ValueType, ValueType),
81
82    #[error("{0}")]
83    IoError(#[source] std::io::Error),
84
85    /// We're just not done yet.  Message that the feature is recognized but not yet
86    /// implemented.
87    #[error("not yet implemented: {0}")]
88    NotYetImplemented(String),
89
90    /// A user-defined transaction function (`:db/fn`) failed, returned bad
91    /// tx-data, or recursed past the depth limit. The message carries the
92    /// `:db.error/txfn-*` code and the function's ident.
93    #[error("{0}")]
94    TransactionFunction(String),
95
96    // It would be better to capture the underlying `rusqlite::Error`, but that type doesn't
97    // implement many useful traits, including `Clone`, `Eq`, and `PartialEq`.
98    #[error("SQL error: {0}, cause: {1}")]
99    RusqliteError(String, String),
100
101    #[error("{0}")]
102    EdnParseError(#[source] edn::ParseError),
103
104    #[error("{0}")]
105    DbError(#[source] DbError),
106
107    #[error("{0}")]
108    AlgebrizerError(#[source] AlgebrizerError),
109
110    #[error("{0}")]
111    ProjectorError(#[source] ProjectorError),
112
113    #[error("{0}")]
114    PullError(#[source] PullError),
115
116    #[error("{0}")]
117    SQLError(#[source] SQLError),
118
119    #[error("{0}")]
120    UuidError(#[source] uuid::Error),
121}
122
123impl From<std::io::Error> for MentatError {
124    fn from(error: std::io::Error) -> Self {
125        MentatError::IoError(error)
126    }
127}
128
129impl From<sql_traits::conn::SqlError> for MentatError {
130    fn from(error: sql_traits::conn::SqlError) -> Self {
131        MentatError::RusqliteError(error.message, String::new())
132    }
133}
134
135impl From<rusqlite::Error> for MentatError {
136    fn from(error: rusqlite::Error) -> Self {
137        let cause = match error.source() {
138            Some(e) => e.to_string(),
139            None => "".to_string(),
140        };
141        MentatError::RusqliteError(error.to_string(), cause)
142    }
143}
144
145impl From<uuid::Error> for MentatError {
146    fn from(error: uuid::Error) -> Self {
147        MentatError::UuidError(error)
148    }
149}
150
151impl From<edn::ParseError> for MentatError {
152    fn from(error: edn::ParseError) -> Self {
153        MentatError::EdnParseError(error)
154    }
155}
156
157impl From<DbError> for MentatError {
158    fn from(error: DbError) -> Self {
159        MentatError::DbError(error)
160    }
161}
162
163impl From<AlgebrizerError> for MentatError {
164    fn from(error: AlgebrizerError) -> Self {
165        MentatError::AlgebrizerError(error)
166    }
167}
168
169impl From<ProjectorError> for MentatError {
170    fn from(error: ProjectorError) -> Self {
171        MentatError::ProjectorError(error)
172    }
173}
174
175impl From<PullError> for MentatError {
176    fn from(error: PullError) -> Self {
177        MentatError::PullError(error)
178    }
179}
180
181impl From<SQLError> for MentatError {
182    fn from(error: SQLError) -> Self {
183        MentatError::SQLError(error)
184    }
185}