mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
show which side the template error occurred on
This commit is contained in:
parent
ed8c1ae9c5
commit
bd96c27096
5 changed files with 47 additions and 36 deletions
|
@ -52,6 +52,7 @@ message InvalidInputError {
|
|||
|
||||
message TemplateParseError {
|
||||
string info = 1;
|
||||
bool q_side = 2;
|
||||
}
|
||||
|
||||
message TemplateRequirementsIn {
|
||||
|
|
|
@ -121,7 +121,14 @@ def render_card(
|
|||
try:
|
||||
output = render_card_from_context(ctx)
|
||||
except anki.rsbackend.BackendException as e:
|
||||
errmsg = _("Card template has a problem:") + f"<br>{e}"
|
||||
# fixme: specific exception in 2.1.21
|
||||
err = e.args[0].template_parse
|
||||
if err.q_side:
|
||||
side = _("Front")
|
||||
else:
|
||||
side = _("Back")
|
||||
errmsg = _("{} template has a problem:").format(side) + f"<br>{e}"
|
||||
errmsg += "<br><a href=https://anki.tenderapp.com/kb/problems/card-template-has-a-problem>{}</a>".format(_("More info"))
|
||||
output = TemplateRenderOutput(
|
||||
question_text=errmsg,
|
||||
answer_text=errmsg,
|
||||
|
|
|
@ -27,7 +27,9 @@ impl std::convert::From<AnkiError> for pt::BackendError {
|
|||
use pt::backend_error::Value as V;
|
||||
let value = match err {
|
||||
AnkiError::InvalidInput { info } => V::InvalidInput(pt::InvalidInputError { info }),
|
||||
AnkiError::TemplateError { info } => V::TemplateParse(pt::TemplateParseError { info }),
|
||||
AnkiError::TemplateError { info, q_side } => {
|
||||
V::TemplateParse(pt::TemplateParseError { info, q_side })
|
||||
}
|
||||
};
|
||||
|
||||
pt::BackendError { value: Some(value) }
|
||||
|
|
|
@ -11,7 +11,7 @@ pub enum AnkiError {
|
|||
InvalidInput { info: String },
|
||||
|
||||
#[fail(display = "invalid card template: {}", info)]
|
||||
TemplateError { info: String },
|
||||
TemplateError { info: String, q_side: bool },
|
||||
}
|
||||
|
||||
// error helpers
|
||||
|
@ -34,33 +34,3 @@ pub enum TemplateError {
|
|||
field: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<TemplateError> for AnkiError {
|
||||
fn from(terr: TemplateError) -> Self {
|
||||
AnkiError::TemplateError {
|
||||
info: match terr {
|
||||
TemplateError::NoClosingBrackets(context) => {
|
||||
format!("missing '}}}}' in '{}'", context)
|
||||
}
|
||||
TemplateError::ConditionalNotClosed(tag) => format!("missing '{{{{/{}}}}}'", tag),
|
||||
TemplateError::ConditionalNotOpen {
|
||||
closed,
|
||||
currently_open,
|
||||
} => {
|
||||
if let Some(open) = currently_open {
|
||||
format!("Found {{{{/{}}}}}, but expected {{{{/{}}}}}", closed, open)
|
||||
} else {
|
||||
format!(
|
||||
"Found {{{{/{}}}}}, but missing '{{{{#{}}}}}' or '{{{{^{}}}}}'",
|
||||
closed, closed, closed
|
||||
)
|
||||
}
|
||||
}
|
||||
TemplateError::FieldNotFound { field, filters } => format!(
|
||||
"found '{{{{{}{}}}}}', but there is no field called '{}'",
|
||||
filters, field, field
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::err::{Result, TemplateError};
|
||||
use crate::err::{AnkiError, Result, TemplateError};
|
||||
use crate::template_filters::apply_filters;
|
||||
use lazy_static::lazy_static;
|
||||
use nom;
|
||||
|
@ -189,6 +189,33 @@ fn parse_inner<'a, I: Iterator<Item = TemplateResult<Token<'a>>>>(
|
|||
}
|
||||
}
|
||||
|
||||
fn template_error_to_anki_error(err: TemplateError, q_side: bool) -> AnkiError {
|
||||
AnkiError::TemplateError {
|
||||
info: match err {
|
||||
TemplateError::NoClosingBrackets(context) => format!("Missing '}}}}' in '{}'", context),
|
||||
TemplateError::ConditionalNotClosed(tag) => format!("Missing '{{{{/{}}}}}'", tag),
|
||||
TemplateError::ConditionalNotOpen {
|
||||
closed,
|
||||
currently_open,
|
||||
} => {
|
||||
if let Some(open) = currently_open {
|
||||
format!("Found {{{{/{}}}}}, but expected {{{{/{}}}}}", closed, open)
|
||||
} else {
|
||||
format!(
|
||||
"Found {{{{/{}}}}}, but missing '{{{{#{}}}}}' or '{{{{^{}}}}}'",
|
||||
closed, closed, closed
|
||||
)
|
||||
}
|
||||
}
|
||||
TemplateError::FieldNotFound { field, filters } => format!(
|
||||
"Found '{{{{{}{}}}}}', but there is no field called '{}'",
|
||||
filters, field, field
|
||||
),
|
||||
},
|
||||
q_side,
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy support
|
||||
//----------------------------------------
|
||||
|
||||
|
@ -438,12 +465,16 @@ pub fn render_card(
|
|||
|
||||
// question side
|
||||
let qnorm = without_legacy_template_directives(qfmt);
|
||||
let qnodes = ParsedTemplate::from_text(qnorm.as_ref())?.render(&context)?;
|
||||
let qnodes = ParsedTemplate::from_text(qnorm.as_ref())
|
||||
.and_then(|tmpl| tmpl.render(&context))
|
||||
.map_err(|e| template_error_to_anki_error(e, true))?;
|
||||
|
||||
// answer side
|
||||
context.question_side = false;
|
||||
let anorm = without_legacy_template_directives(afmt);
|
||||
let anodes = ParsedTemplate::from_text(anorm.as_ref())?.render(&context)?;
|
||||
let anodes = ParsedTemplate::from_text(anorm.as_ref())
|
||||
.and_then(|tmpl| tmpl.render(&context))
|
||||
.map_err(|e| template_error_to_anki_error(e, false))?;
|
||||
|
||||
Ok((qnodes, anodes))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue