catch invalid regex in search

https://github.com/ankitects/anki/pull/652
This commit is contained in:
Damien Elmes 2020-06-09 11:29:40 +10:00
parent 43da12a445
commit c77d017135
5 changed files with 23 additions and 7 deletions

View file

@ -171,7 +171,7 @@ class DataModel(QAbstractTableModel):
def search(self, txt: str) -> None:
self.beginReset()
self.cards = []
invalid = False
error_message: Optional[str] = None
try:
ctx = SearchContext(search=txt)
gui_hooks.browser_will_search(ctx)
@ -180,13 +180,12 @@ class DataModel(QAbstractTableModel):
gui_hooks.browser_did_search(ctx)
self.cards = ctx.card_ids
except Exception as e:
print("search failed:", e)
invalid = True
error_message = str(e)
finally:
self.endReset()
if invalid:
showWarning(_("Invalid search - please check for typing mistakes."))
if error_message:
showWarning(error_message)
def reset(self):
self.beginReset()

1
rslib/ftl/search.ftl Normal file
View file

@ -0,0 +1 @@
search-invalid = Invalid search - please check for typing mistakes.

View file

@ -145,6 +145,7 @@ fn anki_error_to_proto_error(err: AnkiError, i18n: &I18n) -> pb::BackendError {
AnkiError::NotFound => V::NotFoundError(Empty {}),
AnkiError::Existing => V::Exists(Empty {}),
AnkiError::DeckIsFiltered => V::DeckIsFiltered(Empty {}),
AnkiError::SearchError(_) => V::InvalidInput(pb::Empty {}),
};
pb::BackendError {

View file

@ -54,6 +54,9 @@ pub enum AnkiError {
#[fail(display = "Unable to place item in/under a filtered deck.")]
DeckIsFiltered,
#[fail(display = "Invalid search.")]
SearchError(Option<String>),
}
// error helpers
@ -109,6 +112,13 @@ impl AnkiError {
DBErrorKind::Corrupt => info.clone(),
_ => format!("{:?}", self),
},
AnkiError::SearchError(details) => {
if let Some(details) = details {
details.to_owned()
} else {
i18n.tr(TR::SearchInvalid).to_string()
}
}
_ => format!("{:?}", self),
}
}
@ -138,6 +148,11 @@ 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 reason.contains("regex parse error") {
return AnkiError::SearchError(Some(reason.to_owned()));
}
}
AnkiError::DBError {
info: format!("{:?}", err),
kind: DBErrorKind::Other,

View file

@ -119,8 +119,8 @@ pub(super) fn parse(input: &str) -> Result<Vec<Node>> {
return Ok(vec![Node::Search(SearchNode::WholeCollection)]);
}
let (_, nodes) = all_consuming(group_inner)(input)
.map_err(|_e| AnkiError::invalid_input("unable to parse search"))?;
let (_, nodes) =
all_consuming(group_inner)(input).map_err(|_e| AnkiError::SearchError(None))?;
Ok(nodes)
}