Open cfm opened 1 day ago
I haven't been able to reproduce this nor obviously trace what's happening...I suppose you don't have the full traceback anymore?
Previously:
try:
reply = storage.get_reply(self.session, exception.uuid)
self.reply_download_failed.emit(reply.source.uuid, reply.uuid, str(reply))
except Exception as e:
Now:
reply = storage.get_reply(self.session, exception.uuid)
if reply:
self.reply_download_failed.emit(reply.source.uuid, reply.uuid, str(reply))
else:
So any old AttributeError would've been caught.
Interestingly on_file_download_failure types it as just Exception
while on_message_download_failure
/on_reply_download_failure
are specifically DownloadException
.
Oops, sorry, @legoktm: see updated steps to reproduce after #2252 above. This particular failure mode under pytest doesn't give a full traceback without further instrumentation.
thanks, I was able to reproduce now! Digging in a bit.
So here's the underlying traceback of the exception that then fails in the download handling:
Traceback (most recent call last):
File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/queue.py", line 230, in process
self.current_job._do_call_api(self.api_client, session)
File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/base.py", line 77, in _do_call_api
result = self.call_api(api_client, session)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/downloads.py", line 123, in call_api
db_object = self.get_db_object(session)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/github/freedomofpress/securedrop-client/client/securedrop_client/api_jobs/downloads.py", line 245, in get_db_object
return session.query(Reply).filter_by(uuid=self.uuid).one()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/.cache/pypoetry/virtualenvs/securedrop-client-OfHWkjU1-py3.11/lib64/python3.11/site-packages/sqlalchemy/orm/query.py", line 3282, in one
raise orm_exc.NoResultFound("No row was found for one()")
sqlalchemy.orm.exc.NoResultFound: No row was found for one()
(obtained with traceback.print_exception(exception)
)
I'm going to submit two PRs, first is the one I already posted, which broadens exception handling because there are still other exceptions that can be raised that could trigger this error in the exception handling.
The second will change DownloadJob.get_db_object() to use one_or_none()
just like #2231 and then handle the None case with an explicit DownloadException.
Description
After #2231, a
NoResultFound
exception can cause a furtherAttributeError
insecuredrop_client.logic.Controller.on_reply_download_failure()
.Steps to Reproduce
Discovered in test runs of f6bd2c92ddb6a3c17b01a4e9c2a67ebdd05d44fe without this padding—
https://github.com/freedomofpress/securedrop-client/blob/f6bd2c92ddb6a3c17b01a4e9c2a67ebdd05d44fe/client/tests/functional/test_delete_sources.py#L32-L33
—suggesting that it's a race in downloading something that's been deleted. After #2252, reproduce with:
Expected Behavior
Either
on_reply_download_failure()
should only take aDownloadException
, or it should not assume all exceptions it handles have auuid
attribute.Actual Behavior