From e0a3768bf3f92cb6c30d0e9bab45092aa99112aa Mon Sep 17 00:00:00 2001 From: Abdo Date: Thu, 6 Jun 2024 13:20:19 +0300 Subject: [PATCH] Mention missing field's name in CardTypeError (#3225) --- ftl/core/card-templates.ftl | 1 + rslib/src/error/mod.rs | 15 ++++++++------- rslib/src/notetype/mod.rs | 16 ++++++++++------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/ftl/core/card-templates.ftl b/ftl/core/card-templates.ftl index 7c0b0094e..b61fcec90 100644 --- a/ftl/core/card-templates.ftl +++ b/ftl/core/card-templates.ftl @@ -26,6 +26,7 @@ card-templates-no-front-field = Expected to find a field replacement on the fron card-templates-missing-cloze = Expected to find '{ "{{" }cloze:Text{ "}}" }' or similar on the front and back of the card template. card-templates-extraneous-cloze = 'cloze:' can only be used on cloze notetypes. card-templates-see-preview = See the preview for more information. +card-templates-field-not-found = Field '{ $field }' not found. card-templates-changes-saved = Changes saved. card-templates-discard-changes = Discard changes? card-templates-add-card-type = Add Card Type... diff --git a/rslib/src/error/mod.rs b/rslib/src/error/mod.rs index e51fbb80e..cb4adedfe 100644 --- a/rslib/src/error/mod.rs +++ b/rslib/src/error/mod.rs @@ -138,9 +138,11 @@ impl AnkiError { AnkiError::CardTypeError { source } => { let header = tr.card_templates_invalid_template_number(source.ordinal + 1, &source.notetype); - let details = match source.source { - CardTypeErrorDetails::TemplateParseError - | CardTypeErrorDetails::NoSuchField => tr.card_templates_see_preview(), + let details = match &source.source { + CardTypeErrorDetails::TemplateParseError => tr.card_templates_see_preview(), + CardTypeErrorDetails::NoSuchField { field } => { + tr.card_templates_field_not_found(field) + } CardTypeErrorDetails::NoFrontField => tr.card_templates_no_front_field(), CardTypeErrorDetails::Duplicate { index } => { tr.card_templates_identical_front(index + 1) @@ -196,9 +198,8 @@ impl AnkiError { Self::CardTypeError { source: CardTypeError { source, .. }, } => Some(match source { - CardTypeErrorDetails::TemplateParseError | CardTypeErrorDetails::NoSuchField => { - HelpPage::CardTypeTemplateError - } + CardTypeErrorDetails::TemplateParseError => HelpPage::CardTypeTemplateError, + CardTypeErrorDetails::NoSuchField { field: _ } => HelpPage::CardTypeTemplateError, CardTypeErrorDetails::Duplicate { .. } => HelpPage::CardTypeDuplicate, CardTypeErrorDetails::NoFrontField => HelpPage::CardTypeNoFrontField, CardTypeErrorDetails::MissingCloze => HelpPage::CardTypeMissingCloze, @@ -320,7 +321,7 @@ pub enum CardTypeErrorDetails { TemplateParseError, Duplicate { index: usize }, NoFrontField, - NoSuchField, + NoSuchField { field: String }, MissingCloze, ExtraneousCloze, } diff --git a/rslib/src/notetype/mod.rs b/rslib/src/notetype/mod.rs index da85d89ac..7afae3741 100644 --- a/rslib/src/notetype/mod.rs +++ b/rslib/src/notetype/mod.rs @@ -410,8 +410,12 @@ impl Notetype { if q_fields.is_empty() { return Err(CardTypeErrorDetails::NoFrontField); } - if self.unknown_field_name(q_fields.union(&a.all_referenced_field_names())) { - return Err(CardTypeErrorDetails::NoSuchField); + if let Some(unknown_field) = + self.first_unknown_field_name(q_fields.union(&a.all_referenced_field_names())) + { + return Err(CardTypeErrorDetails::NoSuchField { + field: unknown_field.to_string(), + }); } Ok(()) } else { @@ -419,14 +423,14 @@ impl Notetype { } } - /// True if any non-empty name in names does not denote a special field or - /// a field of this notetype. - fn unknown_field_name(&self, names: T) -> bool + /// Return the first non-empty name in names that does not denote a special + /// field or a field of this notetype. + fn first_unknown_field_name(&self, names: T) -> Option where T: IntoIterator, I: AsRef, { - names.into_iter().any(|name| { + names.into_iter().find(|name| { // The empty field name is allowed as it may be used by add-ons. !name.as_ref().is_empty() && !SPECIAL_FIELDS.contains(&name.as_ref())