Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error messages are not so useful #137

Open
ohare93 opened this issue Sep 6, 2020 · 1 comment
Open

Error messages are not so useful #137

ohare93 opened this issue Sep 6, 2020 · 1 comment
Labels

Comments

@ohare93
Copy link

ohare93 commented Sep 6, 2020

I started using Yamale in order to give more detailed error messages to users when they enter in incorrect Yaml, to help direct where the issues are. This has been an overall success, but there's still some confusion as there are more error messages than I expected.

Take the following example

Schema

list(
  map(include('generate_deck_parts'), key=regex('generate_deck_parts')),
  map(include('generate_csv'), key=regex('generate_csv')),
  map(include('generate_crowd_anki'), key=regex('generate_crowd_anki'))
)

---

generate_crowd_anki:
  folder: str()
  headers: str()
  notes: include('notes_to_source')
  note_models: include('note_models_to_source')
  media: any(include('ca_media'), bool(), required=False)

ca_media:
  from_notes: bool()
  from_note_models: bool()

note_models_to_source:
  deck_parts: list(include('note_model_to_source'))

note_model_to_source:
  deck_part: str()

notes_to_source:
  deck_part: str()
  sort_order: list(str(), required=False)
  reverse_sort: bool(required=False)
  additional_items_to_add: map(str(), key=str(), required=False)

Data

- generate_deck_parts:
    ....
- generate_csv:
    ....
- generate_crowd_anki:
    folder: exports/crowdankidecks/csv_to_crowdanki1/
    headers: default
    notes:
      deck_part: csv_first_attempt
      #sort_order: [note_model, guid]
      #reverse_sort: false
      # additional_items_to_add: {key: value}
    note_models:
      deck_parts:
        - deck_part: LL Noun
        - deck_part: LL Verb
        - deck_part: LL Word
    media:
      from_notes: true
      from_note_models: false
      bad_key: test                      <------------------------------------------------- Bad key

Error

Validating this gives the errors:

	1: Key error - 'generate_crowd_anki' is not a regex match.
	1: Key error - 'generate_crowd_anki' is not a regex match.
	1.generate_crowd_anki.media.bad_thing: Unexpected element
	1.generate_crowd_anki.media: '{'from_notes': True, 'from_note_models': False, 'bad_thing': 'test'}' is not a bool.

Where the 3rd line is the only actual error I am interested in 😞

  1. Why are the first two errors there? They seem to be about the other two perfectly valid list items, but only show when this one breaks 🤔
  2. The 3rd line does not specify that it is trying to parse it as a ca_media, which could help with clarity.
  3. Sure, Media is neither a bool or a ca_media, but the 4th line just says "Is not a bool", which is confusing. Something like "media is neither a 'ca_media' or a bool" would be technically accurate and not confusing.

Does this perhaps have something to do with my Yaml being a top level list? I ask because I had some even funkier isses in a previous version where I was not looking for specific keys in the list of dictionaries.

Full Schema and Yaml

Schema

list(map(include('generate_deck_parts'), include('generate_csv'), include('generate_crowd_anki'), key=str()))

---

generate_deck_parts:
  list(map(include('from_csv'), include('from_crowd_anki'), include('from_deck_parts'), key=generatedeckpartstask()))



from_crowd_anki:
  folder: str()
  notes: include('from_ca_notes', required=False)
  note_models: list(include('from_ca_note_models'), required=False)
  headers: include('from_ca_headers', required=False)
  media: any(bool(), include('ca_media'), required=False)


generate_crowd_anki:
  folder: str()
  headers: str()
  notes: include('notes_to_source')
  note_models: include('note_models_to_source')
  media: any(bool(), include('ca_media'), required=False)



from_ca_notes:
  name: str()
  sort_order: list(str(), required=False)
  save_to_file: str(required=False)

from_ca_note_models:
  name: str()
  model_name: str(required=False)
  save_to_file: str(required=False)

from_ca_headers:
  name: str()
  save_to_file: str(required=False)

ca_media:
  from_notes: bool()
  from_note_models: bool()

note_models_to_source:
  deck_parts: list(include('note_model_to_source'))

note_model_to_source:
  deck_part: str()

notes_to_source:
  deck_part: str()
  sort_order: list(str(), required=False)
  reverse_sort: bool(required=False)
  additional_items_to_add: map(str(), key=str(), required=False)




from_deck_parts:
  notes: list(include('deck_part_to_read'), required=False)
  note_models: list(include('deck_part_to_read'), required=False)
  headers: list(include('deck_part_to_read'), required=False)

deck_part_to_read:
  name: str()
  file: str()



from_csv:
  notes:
    name: str()
    save_to_file: str(required=False)
    note_model_mappings: list(include('note_model_mapping'))
    file_mappings: list(include('file_mapping'))

generate_csv:
  notes: str()
  note_model_mappings: list(include('note_model_mapping'))
  file_mappings: list(include('file_mapping'))

note_model_mapping:
  note_models: list(str())
  columns_to_fields: map(str(), key=str())
  personal_fields: list(str())

file_mapping:
  file: str()
  note_model: str(required=False)
  sort_by_columns: list(str(), required=False)
  reverse_sort: bool(required=False)
  derivatives: list(include('file_mapping'), required=False)

Data

- generate_deck_parts:
    - from_crowd_anki:
        folder: exports/crowdankidecks/csv_to_crowdanki1/
        notes:
          name: test_from_CA
          sort_order: [note_model_name, guid]
          save_to_file: deck_parts/notes/csv_first_attempt.yaml
        note_models:
          - name: LL Noun
            model_name: LL Noun
            save_to_file: deck_parts/note_models/LL_Noun.yaml
          - name: LL Verb
            model_name: LL Verb
            save_to_file: deck_parts/note_models/LL_Verb.yaml
          - name: LL Word
            model_name: LL Word
            save_to_file: deck_parts/note_models/LL_Word.yaml
        headers:
          name: default
          save_to_file: deck_parts/headers/default.yaml
        media:
          from_notes: true
          from_note_models: true
          # Location
          # Rename files?
          # filter

    - from_deck_part:
        note_models:
          - name: LL Noun
            file: deck_parts/note_models/LL_Noun
          - name: LL Verb
            file: deck_parts/note_models/LL_Verb
          - name: LL Word
            file: deck_parts/note_models/LL_Word
        notes:
          - name: csv_first_attempt
            file: deck_parts/notes/csv_first_attempt
        headers:
          - name: default
            file: deck_parts/headers/default

    - from_csv:
        notes:
          name: csv_first_attempt
          save_to_file: deck_parts/notes/csv_first_attempt.yaml

          note_model_mappings:
            - note_models:
                - LL Word
                - LL Verb
                - LL Noun
              columns_to_fields:
                guid: guid
                tags: tags

                english: Word
                danish: X Word
                danish audio: X Pronunciation (Recording and/or IPA)
                esperanto: Y Word
                esperanto audio: Y Pronunciation (Recording and/or IPA)

                present: Form Present
                past: Form Past
                present perfect: Form Perfect Present

                plural: Plural
                indefinite plural: Indefinite Plural
                definite plural: Definite Plural
              personal_fields:
                - picture
                - extra
                - morphman_focusmorph

          file_mappings:
            - file: source/vocab/main.csv
              note_model: LL Word
              sort_by_columns: [english]
              reverse_sort: no

              derivatives:
                - file: source/vocab/derivatives/danish/danish_verbs.csv
                  note_model: LL Verb
                - file: source/vocab/derivatives/danish/danish_nouns.csv
                  note_model: LL Noun

- generate_crowd_anki:
    folder: exports/crowdankidecks/csv_to_crowdanki1/
    headers: default
    notes:
      deck_part: csv_first_attempt
      #sort_order: [note_model, guid]
      #reverse_sort: false
      # additional_items_to_add: {key: value}
    note_models:
      deck_parts:
        - deck_part: LL Noun
        - deck_part: LL Verb
        - deck_part: LL Word

      #Name: LL Noun
      #mode: automatic
      #error_handling:
        # on_extra: error
        # on_missing: warning
    media:
      from_notes: true
      from_note_models: false
      bad_thing: test
- generate_crowd_anki:
    folder: exports/crowdankidecks/csv_to_crowdanki1/
    headers: default
    notes:
      deck_part: csv_first_attempt
      #sort_order: [note_model, guid]
      #reverse_sort: false
      # additional_items_to_add: {key: value}
    note_models:
      deck_parts:
        - deck_part: LL Noun
        - deck_part: LL Verb
        - deck_part: LL Word

      #Name: LL Noun
      #mode: automatic
      #error_handling:
        # on_extra: error
        # on_missing: warning
    media:
      from_notes: true
      from_note_models: false

- generate_csv_collection:
    notes: csv_first_attempt

    note_model_mappings:
      - note_models:
          - LL Word
          - LL Verb
          - LL Noun
        columns_to_fields:
          guid: guid
          tags: tags

          english: Word
          danish: X Word
          danish audio: X Pronunciation (Recording and/or IPA)
          esperanto: Y Word
          esperanto audio: Y Pronunciation (Recording and/or IPA)

          present: Form Present
          past: Form Past
          present perfect: Form Perfect Present

          plural: Plural
          indefinite plural: Indefinite Plural
          definite plural: Definite Plural
        personal_fields:
          - picture
          - extra
          - morphman_focusmorph

    file_mappings:
      - file: source/vocab/main.csv
        note_model: LL Word
        sort_by_columns: [english]
        reverse_sort: false

        derivatives:
          - file: source/vocab/derivatives/danish/danish_verbs.csv
            note_model: LL Verb
            sort_by_columns: [danish]
          - file: source/vocab/derivatives/danish/danish_nouns.csv
            note_model: LL Noun
            sort_by_columns: [danish]

Which generates the errors:

	1.generate_crowd_anki: '{'folder': 'exports/crowdankidecks/csv_to_crowdanki1/', 'headers': 'default', 'notes': {'deck_part': 'csv_first_attempt'}, 'note_models': {'deck_parts': [{'deck_part': 'LL Noun'}, {'deck_part': 'LL Verb'}, {'deck_part': 'LL Word'}]}, 'media': {'from_notes': True, 'from_note_models': False, 'bad_thing': 'test'}}' is not a list.
	1.generate_crowd_anki.folder: Unexpected element
	1.generate_crowd_anki.headers: Unexpected element
	1.generate_crowd_anki.media: Unexpected element
	1.generate_crowd_anki.note_models: Unexpected element
	1.generate_crowd_anki.notes: '{'deck_part': 'csv_first_attempt'}' is not a str.
	1.generate_crowd_anki.note_model_mappings: Required field missing
	1.generate_crowd_anki.file_mappings: Required field missing
	1.generate_crowd_anki.media: '{'from_notes': True, 'from_note_models': False, 'bad_thing': 'test'}' is not a bool.
	1.generate_crowd_anki.media.bad_thing: Unexpected element

With the error generate_crowd_anki.file_mappings: Required field missing even though that is not a value on that type of object, but one of the other ones 😱

Anyways, apologies for the data dump. Any light anyone could shed onto my issues here would be well appreciated. I simply want to check for a specific key and match that to a specific object, in a top level list. If I am doing something wrong here I'd love to hear and correct it! 😁

@mildebrandt
Copy link

Thanks for the detailed report. On the surface, this seems to be an error in the processing of the list validator when combined with more complex validators such as the map validator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants