mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
catch invalid regex in search
https://github.com/ankitects/anki/pull/652
This commit is contained in:
parent
43da12a445
commit
c77d017135
5 changed files with 23 additions and 7 deletions
|
@ -171,7 +171,7 @@ class DataModel(QAbstractTableModel):
|
||||||
def search(self, txt: str) -> None:
|
def search(self, txt: str) -> None:
|
||||||
self.beginReset()
|
self.beginReset()
|
||||||
self.cards = []
|
self.cards = []
|
||||||
invalid = False
|
error_message: Optional[str] = None
|
||||||
try:
|
try:
|
||||||
ctx = SearchContext(search=txt)
|
ctx = SearchContext(search=txt)
|
||||||
gui_hooks.browser_will_search(ctx)
|
gui_hooks.browser_will_search(ctx)
|
||||||
|
@ -180,13 +180,12 @@ class DataModel(QAbstractTableModel):
|
||||||
gui_hooks.browser_did_search(ctx)
|
gui_hooks.browser_did_search(ctx)
|
||||||
self.cards = ctx.card_ids
|
self.cards = ctx.card_ids
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("search failed:", e)
|
error_message = str(e)
|
||||||
invalid = True
|
|
||||||
finally:
|
finally:
|
||||||
self.endReset()
|
self.endReset()
|
||||||
|
|
||||||
if invalid:
|
if error_message:
|
||||||
showWarning(_("Invalid search - please check for typing mistakes."))
|
showWarning(error_message)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.beginReset()
|
self.beginReset()
|
||||||
|
|
1
rslib/ftl/search.ftl
Normal file
1
rslib/ftl/search.ftl
Normal file
|
@ -0,0 +1 @@
|
||||||
|
search-invalid = Invalid search - please check for typing mistakes.
|
|
@ -145,6 +145,7 @@ fn anki_error_to_proto_error(err: AnkiError, i18n: &I18n) -> pb::BackendError {
|
||||||
AnkiError::NotFound => V::NotFoundError(Empty {}),
|
AnkiError::NotFound => V::NotFoundError(Empty {}),
|
||||||
AnkiError::Existing => V::Exists(Empty {}),
|
AnkiError::Existing => V::Exists(Empty {}),
|
||||||
AnkiError::DeckIsFiltered => V::DeckIsFiltered(Empty {}),
|
AnkiError::DeckIsFiltered => V::DeckIsFiltered(Empty {}),
|
||||||
|
AnkiError::SearchError(_) => V::InvalidInput(pb::Empty {}),
|
||||||
};
|
};
|
||||||
|
|
||||||
pb::BackendError {
|
pb::BackendError {
|
||||||
|
|
|
@ -54,6 +54,9 @@ pub enum AnkiError {
|
||||||
|
|
||||||
#[fail(display = "Unable to place item in/under a filtered deck.")]
|
#[fail(display = "Unable to place item in/under a filtered deck.")]
|
||||||
DeckIsFiltered,
|
DeckIsFiltered,
|
||||||
|
|
||||||
|
#[fail(display = "Invalid search.")]
|
||||||
|
SearchError(Option<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// error helpers
|
// error helpers
|
||||||
|
@ -109,6 +112,13 @@ impl AnkiError {
|
||||||
DBErrorKind::Corrupt => info.clone(),
|
DBErrorKind::Corrupt => info.clone(),
|
||||||
_ => format!("{:?}", self),
|
_ => format!("{:?}", self),
|
||||||
},
|
},
|
||||||
|
AnkiError::SearchError(details) => {
|
||||||
|
if let Some(details) = details {
|
||||||
|
details.to_owned()
|
||||||
|
} else {
|
||||||
|
i18n.tr(TR::SearchInvalid).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => format!("{:?}", self),
|
_ => format!("{:?}", self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +148,11 @@ impl From<io::Error> for AnkiError {
|
||||||
|
|
||||||
impl From<rusqlite::Error> for AnkiError {
|
impl From<rusqlite::Error> for AnkiError {
|
||||||
fn from(err: rusqlite::Error) -> Self {
|
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 {
|
AnkiError::DBError {
|
||||||
info: format!("{:?}", err),
|
info: format!("{:?}", err),
|
||||||
kind: DBErrorKind::Other,
|
kind: DBErrorKind::Other,
|
||||||
|
|
|
@ -119,8 +119,8 @@ pub(super) fn parse(input: &str) -> Result<Vec<Node>> {
|
||||||
return Ok(vec![Node::Search(SearchNode::WholeCollection)]);
|
return Ok(vec![Node::Search(SearchNode::WholeCollection)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_, nodes) = all_consuming(group_inner)(input)
|
let (_, nodes) =
|
||||||
.map_err(|_e| AnkiError::invalid_input("unable to parse search"))?;
|
all_consuming(group_inner)(input).map_err(|_e| AnkiError::SearchError(None))?;
|
||||||
|
|
||||||
Ok(nodes)
|
Ok(nodes)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue