inspirehep / inspire-next

The INSPIRE repo.
https://inspirehep.net
GNU General Public License v3.0
59 stars 69 forks source link

AttributeError: 'str' object has no attribute 'to_dict' #2983

Closed kaplun closed 6 years ago

kaplun commented 6 years ago

https://sentry.inspirehep.net/inspire-sentry/prod/issues/366/

AttributeError: 'str' object has no attribute 'to_dict'
(5 additional frame(s) were not displayed)
...
  File "werkzeug/test.py", line 884, in run_wsgi_app
    app_rv = app(environ, start_response)
  File "werkzeug/exceptions.py", line 155, in __call__
    response = self.get_response(environ)
  File "werkzeug/exceptions.py", line 146, in get_response
    return Response(self.get_body(environ), self.code, headers)
  File "invenio_rest/errors.py", line 90, in get_body
    errors = self.get_errors()
  File "invenio_rest/errors.py", line 77, in get_errors
    return [e.to_dict() for e in self.errors] if self.errors else None

AttributeError: 'str' object has no attribute 'to_dict'
kaplun commented 6 years ago

This was triggered by visiting: https://labs.inspirehep.net/api/files/b15e3314-42dd-456c-b800-25b24ad913e0/1311923_S0375960114006318.xml_1 which is a file attached to record: https://labs.inspirehep.net/api/literature/1311923 which in principle should be inaccessible to users.

jacquerie commented 6 years ago

As the stacktrace says, bug is not in inspire-next, but somewhere deeper in Invenio. Looking at the line that throws we see that it expects self.errors to be a list of FieldErrors, defined above. This is not true, it instead got a string that starts with 'C'.

RESTException is a base class of all errors in invenio-rest-files, so we should look for code that instantiates an error with a string argument. ensure_state sounds suspicious, and either https://github.com/inveniosoftware/invenio-files-rest/blob/983d0824a2ad199d5578d5df9b044bb6a7996e24/invenio_files_rest/models.py#L164-L167 or https://github.com/inveniosoftware/invenio-files-rest/blob/983d0824a2ad199d5578d5df9b044bb6a7996e24/invenio_files_rest/models.py#L179-L182 look guilty, as they end up instantiating a subclass of RESTException with a string argument that begins by 'C'.

jacquerie commented 6 years ago

Minimal reproduction:

>>> from invenio_files_rest import InvalidOperationError
>>> error = InvalidOperationError("Can't do something")
>>> error.get_body()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jacquerie/.envs/invenio-files-rest/local/lib/python2.7/site-packages/invenio_rest/errors.py", line 90, in get_body
    errors = self.get_errors()
  File "/home/jacquerie/.envs/invenio-files-rest/local/lib/python2.7/site-packages/invenio_rest/errors.py", line 77, in get_errors
    return [e.to_dict() for e in self.errors] if self.errors else None
AttributeError: 'str' object has no attribute 'to_dict'
jacquerie commented 6 years ago

We can close this, as the bug is definitely upstream.