Open dmsimard opened 5 years ago
It's likely that 0.x has a similar issue, @pabelanger shared this trace:
2019-06-13 14:15:12.491754 | TASK [Generate ARA HTML output]
[2019-06-13 14:15:21,132] ERROR in app: Exception on /result/e7ea405b-e824-4969-995f-45207985e7e7/ [GET]
Traceback (most recent call last):
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 2311, in wsgi_app
response = self.full_dispatch_request()
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 1835, in full_dispatch_request
return self.finalize_request(rv)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 1850, in finalize_request
response = self.make_response(rv)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 1987, in make_response
rv = self.response_class(rv, status=status, headers=headers)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/werkzeug/wrappers/base_response.py", line 212, in __init__
self.set_data(response)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/werkzeug/wrappers/base_response.py", line 353, in set_data
value = value.encode(self.charset)
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcd2' in position 11126: surrogates not allowed
Exception on /result/e7ea405b-e824-4969-995f-45207985e7e7/ [GET]
Traceback (most recent call last):
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 2311, in wsgi_app
response = self.full_dispatch_request()
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 1835, in full_dispatch_request
return self.finalize_request(rv)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 1850, in finalize_request
response = self.make_response(rv)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/flask/app.py", line 1987, in make_response
rv = self.response_class(rv, status=status, headers=headers)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/werkzeug/wrappers/base_response.py", line 212, in __init__
self.set_data(response)
File "/home/zuul/src/github.com/ansible/ansible-zuul-jobs/.tox/venv/lib/python3.6/site-packages/werkzeug/wrappers/base_response.py", line 353, in set_data
value = value.encode(self.charset)
UnicodeEncodeError: 'utf-8' codec can't encode character '\udcd2' in position 11126: surrogates not allowed
ERROR
{
"delta": "0:00:08.167555",
"end": "2019-06-13 14:15:21.248915",
"msg": "non-zero return code",
"rc": 1,
"start": "2019-06-13 14:15:13.081360"
}
I don't mind looking into this, do you have a general idea where I would focus on?
@pabelanger The failure case for 0.x is different than the one from 1.x. In 0.x, the data is saved properly to the database by the callback and you get the error when doing the html generation. This means you'd be able to reproduce this exception when running the web application off of the database.
The trace is occuring on a specific result /result/e7ea405b-e824-4969-995f-45207985e7e7/
which is routed here:
https://github.com/ansible-community/ara/blob/474e83710c0c5429fd1ef520884af6890bc04cda/ara/views/result.py#L47-L53
The template used to render that is here: https://github.com/ansible-community/ara/blob/stable/0.x/ara/templates/task_result.html
This is where the files are saved by the callback: https://github.com/ansible-community/ara/blob/474e83710c0c5429fd1ef520884af6890bc04cda/ara/plugins/callbacks/log_ara.py#L108-L136
That is indeed helpful, so my first step here, is to start collecting the ara.sqlite file, so we have something to reproduce with.
PLAY [Run preparations] *****************************************************************************************************************************************************************************************************************
[WARNING]: Failure using method (v2_playbook_on_play_start) in callback plugin (<ansible.plugins.callback./usr/local/lib/python3.6/dist-packages/ara/plugins/callback/ara_default.CallbackModule object at 0x7f5f510f0e10>): 'ascii'
codec can't decode byte 0xc3 in position 28: ordinal not in range(128)
This failed not because of the filename but because of the content of the file.
In this example, a metafile of a role with the following content is read. This will cause it to fail.
---
galaxy_info:
author: Sébastien Han
[...]
The affected method appears to be _get_or_create_file
in plugins/callback/ara_default.py
.
It was tested with the current version of ARA 1.1.0 with Ansible 2.6 and Python 3.6.8.
@berendt thanks! We actually try to test for this in the integration tests: https://github.com/ansible-community/ara/blob/a0cf0cb8371aa7f6071a9a35e8d1bf5c7c9551c7/tests/integration/smoke.yaml#L53-L66
As far as the tests go, that particular file is saved properly in:
I don't know what could be causing this yet and I don't think there's anything in the upcoming release of 1.2 that would help with this. Do you get any hints if you turn up the verbosity ? For example:
export ARA_DEBUG=true; export ARA_LOG_LEVEL=DEBUG
ansible-playbook -vvv
The full stack trace could be helpful.
I suspect rather an encoding problem of the file itself. Take a look at it. But this is not a blocker for a release.
Not fixed in 1.0 despite adding an integration test (that hasn't failed?)
2019-11-18 20:58:54,224 ERROR django.request: Internal Server Error: /api/v1/results
Traceback (most recent call last):
File "/tmp/zuul/lib64/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/tmp/zuul/lib64/python3.6/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/tmp/zuul/lib64/python3.6/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/tmp/zuul/lib64/python3.6/site-packages/django/template/response.py", line 106, in render
self.content = self.rendered_content
File "/tmp/zuul/lib64/python3.6/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/tmp/zuul/lib64/python3.6/site-packages/rest_framework/renderers.py", line 111, in render
return ret.encode()
UnicodeEncodeError: 'utf-8' codec can't encode character '\udc80' in position 467: surrogates not allowed
2019-11-18 20:58:54,240 ERROR ara.clients.http: Failed to post on /api/v1/results: {'playbook': 7, 'task': 165, 'host': 11, 'play': 15, 'content': {'changed': False, 'cmd': ['echo', '-e', '\\x80abc'], 'delta': '0:00:00.001269', 'end': '2019-11-18 20:58:54.183919', 'invocation': {'module_args': {'_raw_params': "echo -e '\\x80abc'", '_uses_shell': False, 'argv': None, 'chdir': None, 'creates': None, 'executable': None, 'removes': None, 'stdin': None, 'stdin_add_newline': True, 'strip_empty_ends': True, 'warn': True}}, 'rc': 0, 'start': '2019-11-18 20:58:54.182650', 'stderr': '', 'stderr_lines': [], 'stdout': '\udc80abc', 'stdout_lines': ['\udc80abc']}, 'status': 'ok', 'started': '2019-11-18T20:58:53.816646-05:00', 'ended': '2019-11-18T20:58:54.200620', 'changed': False, 'ignore_errors': False}
2019-11-18 20:58:54,241 ERROR ara.clients.http: Failed to post on /api/v1/results: {'playbook': 7, 'task': 165, 'host': 11, 'play': 15, 'content': {'changed': False, 'cmd': ['echo', '-e', '\\x80abc'], 'delta': '0:00:00.001269', 'end': '2019-11-18 20:58:54.183919', 'invocation': {'module_args': {'_raw_params': "echo -e '\\x80abc'", '_uses_shell': False, 'argv': None, 'chdir': None, 'creates': None, 'executable': None, 'removes': None, 'stdin': None, 'stdin_add_newline': True, 'strip_empty_ends': True, 'warn': True}}, 'rc': 0, 'start': '2019-11-18 20:58:54.182650', 'stderr': '', 'stderr_lines': [], 'stdout': '\udc80abc', 'stdout_lines': ['\udc80abc']}, 'status': 'ok', 'started': '2019-11-18T20:58:53.816646-05:00', 'ended': '2019-11-18T20:58:54.200620', 'changed': False, 'ignore_errors': False}
[WARNING]: Failure using method (v2_runner_on_ok) in callback plugin (<ansible.plugins.callback./tmp/zuul/lib/python3.6/site-packages/ara/plugins/callback/ara_default.CallbackModule object at 0x7fdb47b02f98>): Expecting value: line 1 column 1 (char 0)
Callback Exception:
File "/tmp/zuul/lib64/python3.6/site-packages/ansible/executor/task_queue_manager.py", line 333, in send_callback
method(*new_args, **kwargs)
File "/tmp/zuul/lib/python3.6/site-packages/ara/plugins/callback/ara_default.py", line 246, in v2_runner_on_ok
self._load_result(result, "ok", **kwargs)
File "/tmp/zuul/lib/python3.6/site-packages/ara/plugins/callback/ara_default.py", line 358, in _load_result
ignore_errors=kwargs.get("ignore_errors", False) or False,
File "/tmp/zuul/lib64/python3.6/site-packages/ara/clients/http.py", line 108, in post
return self._request("post", endpoint, **kwargs)
File "/tmp/zuul/lib64/python3.6/site-packages/ara/clients/http.py", line 99, in _request
return response.json()
File "/tmp/zuul/lib64/python3.6/site-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib64/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
@dmsimard Think this is different. Not general UTF-8.
surrogates not allowed
Stackoverflow means you should try decode('utf8', 'surrogateescape')
.
@berendt yes, you're right. It was getting late and I wanted to keep a note of that trace :) I might end up splitting that into another issue.
The problem for decoding results specifically is that they are often nested in lists or dictionaries. Going through each list item and dictionary key to decode them could be expensive. I need to spend some time on this -- maybe we can get away by decoding the json string like in https://stackoverflow.com/a/18337754/6072068.
maybe not a fix, but a "works for me"
--- ara_default.py 2022-10-14 14:18:19.102689775 +0000
+++ ara_default.py 2022-10-14 14:22:51.006757559 +0000
@@ -526,7 +526,7 @@
content = "Not saved by ARA as configured by 'ignored_files'"
if content is None:
try:
- with open(path, "r") as fd:
+ with open(path, "rU", encoding="utf-8") as fd:
content = fd.read()
except IOError as e:
self.log.error("Unable to open {0} for reading: {1}".format(path, str(e)))
on version 1.5.8
Noticed when running ansible integration tests: