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

Fix YAML error message when error is at the end of the file #73241

Merged

Conversation

samdoran
Copy link
Contributor

@samdoran samdoran commented Jan 14, 2021

SUMMARY

If a YAML file fails to load due to a syntax error in a file, or there is an error in the last line of a file, PyYAML reports the last line number of the file as the index where the error occurred.

When reading the file lines, we use that index to the get the relevant line. If the index value is out of range, the relevant line is lost for error reporting.

Subtract one from the index value to avoid the IndexError in this specific scenario. It is possible to still get an IndexError, which will be handled as it is currently.

Fixes #16456

ISSUE TYPE
  • Bugfix Pull Request
COMPONENT NAME

lib/ansible/errors/__init__.py

ADDITIONAL INFORMATION
  • Update tests

The additional code that tries to avoid empty lines in the error message is not necessary for this fix. I can omit that if others see problems with it.

If a YAML file fails to load due to a syntax error in a file, or there is an error in the last line of a
file, PyYAML reports the last line number of the file as the index where the error occurred.

When reading the file lines, we use that index to the get the relevant line.  If the index value is out
of range, the relevant line is lost for error reporting.

Subtract one from the index value to avoid the IndexError in this specific scenario. It is possible
to still get an IndexError, which will be handled as it is currently.
@ansibot ansibot added affects_2.11 bug This issue/PR relates to a bug. core_review In order to be merged, this PR must follow the core review workflow. has_issue needs_triage Needs a first human triage before being processed. support:community This issue/PR relates to code supported by the Ansible community. support:core This issue/PR relates to code supported by the Ansible Engineering Team. needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. and removed core_review In order to be merged, this PR must follow the core review workflow. labels Jan 14, 2021
@samdoran samdoran marked this pull request as ready for review January 15, 2021 18:39
@ansibot ansibot added core_review In order to be merged, this PR must follow the core review workflow. and removed needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR. labels Jan 15, 2021
@Shrews
Copy link
Contributor

Shrews commented Jan 18, 2021

Hrm, looks like the message does change, but it still references the wrong line number when I use the example from the original reported issue (with an invalid, two-line role meta/main.yml).

Without your change:

% ansible-playbook site.yml 
[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.7.3 (default, Apr 24 2020, 18:51:23) 
[Clang 11.0.3 (clang-1103.0.32.62)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting 
deprecation_warnings=False in ansible.cfg.
[WARNING]: You are running the development version of Ansible. You should only run Ansible from "devel" if you are modifying the Ansible engine, or trying out features
under development. This is a rapidly changing source of code and can become unstable at any point.
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)

Syntax Error while loading YAML.
  found unexpected end of stream

The error appears to be in '/Users/shrews/Devel/playground/t/roles/a/meta/main.yml': line 3, column 1, but may
be elsewhere in the file depending on the exact syntax problem.

(specified line no longer in file, maybe it changed?)

With your change:

% ansible-playbook site.yml
[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller starting with Ansible 2.12. Current version: 3.7.3 (default, Apr 24 2020, 18:51:23) 
[Clang 11.0.3 (clang-1103.0.32.62)]. This feature will be removed from ansible-core in version 2.12. Deprecation warnings can be disabled by setting 
deprecation_warnings=False in ansible.cfg.
[WARNING]: You are running the development version of Ansible. You should only run Ansible from "devel" if you are modifying the Ansible engine, or trying out features
under development. This is a rapidly changing source of code and can become unstable at any point.
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)

Syntax Error while loading YAML.
  found unexpected end of stream

The error appears to be in '/Users/shrews/Devel/playground/t/roles/a/meta/main.yml': line 3, column 1, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

dependencies:
 - { role: b, a_value="{{ "foo" }}" }
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"

@samdoran
Copy link
Contributor Author

@Shrews Unfortunately, that's expected. That's the position we get from YAML. Since it's an "end of stream" error, the error address is effectively the last line and column of the file. I'm not sure how we would go about getting the "correct" position in this situtaion.

err_obj.ansible_pos = (file_name, yaml_exc.problem_mark.line + 1, yaml_exc.problem_mark.column + 1)

@Shrews Shrews removed the needs_triage Needs a first human triage before being processed. label Jan 19, 2021
@Shrews Shrews merged commit e8d4b62 into ansible:devel Jan 19, 2021
@samdoran samdoran deleted the issue/16456-yaml-last-line-pareser-error branch January 19, 2021 15:07
samdoran added a commit to samdoran/ansible that referenced this pull request Jan 19, 2021
…file (ansible#73241)

* Fix YAML error message when error is at the end of the file

If a YAML file fails to load due to a syntax error in a file, or there is an error in the last line of a
file, PyYAML reports the last line number of the file as the index where the error occurred.

When reading the file lines, we use that index to the get the relevant line.  If the index value is out
of range, the relevant line is lost for error reporting.

Subtract one from the index value to avoid the IndexError in this specific scenario. It is possible
to still get an IndexError, which will be handled as it is currently.

* Update existing tests and add new tests
(cherry picked from commit e8d4b62)

Co-authored-by: Sam Doran <sdoran@redhat.com>
samdoran added a commit to samdoran/ansible that referenced this pull request Jan 19, 2021
…ile (ansible#73241)

* Fix YAML error message when error is at the end of the file

If a YAML file fails to load due to a syntax error in a file, or there is an error in the last line of a
file, PyYAML reports the last line number of the file as the index where the error occurred.

When reading the file lines, we use that index to the get the relevant line.  If the index value is out
of range, the relevant line is lost for error reporting.

Subtract one from the index value to avoid the IndexError in this specific scenario. It is possible
to still get an IndexError, which will be handled as it is currently.

* Update existing tests and add new tests
(cherry picked from commit e8d4b62)

Co-authored-by: Sam Doran <sdoran@redhat.com>
relrod pushed a commit that referenced this pull request Feb 5, 2021
…ile (#73241) (#73297)

If a YAML file fails to load due to a syntax error in a file, or there is an error in the last line of a
file, PyYAML reports the last line number of the file as the index where the error occurred.

When reading the file lines, we use that index to the get the relevant line.  If the index value is out
of range, the relevant line is lost for error reporting.

Subtract one from the index value to avoid the IndexError in this specific scenario. It is possible
to still get an IndexError, which will be handled as it is currently.

* Update existing tests and add new tests
(cherry picked from commit e8d4b62)

Co-authored-by: Sam Doran <sdoran@redhat.com>
relrod pushed a commit that referenced this pull request Feb 7, 2021
…file (#73241) (#73296)

If a YAML file fails to load due to a syntax error in a file, or there is an error in the last line of a
file, PyYAML reports the last line number of the file as the index where the error occurred.

When reading the file lines, we use that index to the get the relevant line.  If the index value is out
of range, the relevant line is lost for error reporting.

Subtract one from the index value to avoid the IndexError in this specific scenario. It is possible
to still get an IndexError, which will be handled as it is currently.

* Update existing tests and add new tests
(cherry picked from commit e8d4b62)

Co-authored-by: Sam Doran <sdoran@redhat.com>
@ansible ansible locked and limited conversation to collaborators Feb 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.11 bug This issue/PR relates to a bug. core_review In order to be merged, this PR must follow the core review workflow. has_issue support:community This issue/PR relates to code supported by the Ansible community. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
3 participants