move DB error into separate file; add InvalidRegex error

This commit is contained in:
Damien Elmes 2021-04-01 16:28:23 +10:00
parent f14a631f68
commit 8363fcf2a8
3 changed files with 67 additions and 54 deletions

View File

@ -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 {

55
rslib/src/error/db.rs Normal file
View File

@ -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<Error> 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<FromSqlError> for AnkiError {
fn from(err: FromSqlError) -> Self {
if let FromSqlError::Other(ref err) = err {
if let Some(_err) = err.downcast_ref::<Utf8Error>() {
return AnkiError::DbError {
info: "".to_string(),
kind: DbErrorKind::Utf8,
};
}
}
AnkiError::DbError {
info: format!("{:?}", err),
kind: DbErrorKind::Other,
}
}
}

View File

@ -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<T, E = AnkiError> = std::result::Result<T, E>;
@ -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<io::Error> for AnkiError {
}
}
impl From<rusqlite::Error> 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<rusqlite::types::FromSqlError> 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::<Utf8Error>() {
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<prost::DecodeError> for AnkiError {
}
}
#[derive(Debug, PartialEq)]
pub enum DbErrorKind {
FileTooNew,
FileTooOld,
MissingEntity,
Corrupt,
Locked,
Utf8,
Other,
}
impl From<PathPersistError> for AnkiError {
fn from(e: PathPersistError) -> Self {
AnkiError::IoError {
@ -358,9 +317,7 @@ impl From<PathPersistError> for AnkiError {
}
impl From<regex::Error> 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())
}
}