diff --git a/rslib/src/backend/err.rs b/rslib/src/backend/err.rs index 2e67b5ffc..95fe2aca0 100644 --- a/rslib/src/backend/err.rs +++ b/rslib/src/backend/err.rs @@ -32,6 +32,7 @@ pub(super) fn anki_error_to_proto_error(err: AnkiError, tr: &I18n) -> pb::Backen AnkiError::TemplateSaveError { .. } => V::TemplateParse(pb::Empty {}), AnkiError::ParseNumError => V::InvalidInput(pb::Empty {}), AnkiError::FilteredDeckEmpty => V::FilteredDeckEmpty(pb::Empty {}), + AnkiError::InvalidRegex(_) => V::InvalidInput(pb::Empty {}), }; pb::BackendError { diff --git a/rslib/src/error/db.rs b/rslib/src/error/db.rs new file mode 100644 index 000000000..7cef5c6ac --- /dev/null +++ b/rslib/src/error/db.rs @@ -0,0 +1,55 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +use rusqlite::{types::FromSqlError, Error}; +use std::str::Utf8Error; + +use super::AnkiError; + +#[derive(Debug, PartialEq)] +pub enum DbErrorKind { + FileTooNew, + FileTooOld, + MissingEntity, + Corrupt, + Locked, + Utf8, + Other, +} + +impl From for AnkiError { + fn from(err: Error) -> Self { + if let Error::SqliteFailure(error, Some(reason)) = &err { + if error.code == rusqlite::ErrorCode::DatabaseBusy { + return AnkiError::DbError { + info: "".to_string(), + kind: DbErrorKind::Locked, + }; + } + if reason.contains("regex parse error") { + return AnkiError::InvalidRegex(reason.to_owned()); + } + } + AnkiError::DbError { + info: format!("{:?}", err), + kind: DbErrorKind::Other, + } + } +} + +impl From for AnkiError { + fn from(err: FromSqlError) -> Self { + if let FromSqlError::Other(ref err) = err { + if let Some(_err) = err.downcast_ref::() { + return AnkiError::DbError { + info: "".to_string(), + kind: DbErrorKind::Utf8, + }; + } + } + AnkiError::DbError { + info: format!("{:?}", err), + kind: DbErrorKind::Other, + } + } +} diff --git a/rslib/src/error/mod.rs b/rslib/src/error/mod.rs index 83c0204c1..318936ffd 100644 --- a/rslib/src/error/mod.rs +++ b/rslib/src/error/mod.rs @@ -1,14 +1,18 @@ // Copyright: Ankitects Pty Ltd and contributors // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +mod db; mod search; -pub use search::{ParseError, SearchErrorKind}; +pub use { + db::DbErrorKind, + search::{ParseError, SearchErrorKind}, +}; use crate::i18n::I18n; pub use failure::{Error, Fail}; use reqwest::StatusCode; -use std::{io, str::Utf8Error}; +use std::io; use tempfile::PathPersistError; pub type Result = std::result::Result; @@ -71,6 +75,9 @@ pub enum AnkiError { #[fail(display = "Provided search(es) did not match any cards.")] FilteredDeckEmpty, + + #[fail(display = "Invalid regex provided.")] + InvalidRegex(String), } // error helpers @@ -169,43 +176,6 @@ impl From for AnkiError { } } -impl From for AnkiError { - fn from(err: rusqlite::Error) -> Self { - if let rusqlite::Error::SqliteFailure(error, Some(reason)) = &err { - if error.code == rusqlite::ErrorCode::DatabaseBusy { - return AnkiError::DbError { - info: "".to_string(), - kind: DbErrorKind::Locked, - }; - } - if reason.contains("regex parse error") { - return AnkiError::SearchError(SearchErrorKind::Regex(reason.to_owned())); - } - } - AnkiError::DbError { - info: format!("{:?}", err), - kind: DbErrorKind::Other, - } - } -} - -impl From for AnkiError { - fn from(err: rusqlite::types::FromSqlError) -> Self { - if let rusqlite::types::FromSqlError::Other(ref err) = err { - if let Some(_err) = err.downcast_ref::() { - return AnkiError::DbError { - info: "".to_string(), - kind: DbErrorKind::Utf8, - }; - } - } - AnkiError::DbError { - info: format!("{:?}", err), - kind: DbErrorKind::Other, - } - } -} - #[derive(Debug, PartialEq)] pub enum NetworkErrorKind { Offline, @@ -338,17 +308,6 @@ impl From for AnkiError { } } -#[derive(Debug, PartialEq)] -pub enum DbErrorKind { - FileTooNew, - FileTooOld, - MissingEntity, - Corrupt, - Locked, - Utf8, - Other, -} - impl From for AnkiError { fn from(e: PathPersistError) -> Self { AnkiError::IoError { @@ -358,9 +317,7 @@ impl From for AnkiError { } impl From for AnkiError { - fn from(_err: regex::Error) -> Self { - AnkiError::InvalidInput { - info: "invalid regex".into(), - } + fn from(err: regex::Error) -> Self { + AnkiError::InvalidRegex(err.to_string()) } }