Sentry reports many cases of the xhr object being missing in the
error handler.
Ensure the error handling code doesn't crash because of the missing xhr.
There are two cases where the draft auto-save might fail because the
user is no longer authenticated:
- The user signed-out in another tab,
- The brower quit and re-opened, so the Session cookie expired.
In both cases, the auto-save will never succeed until the user
authenticates again, so displaying a "Retry" button is cruel.
Moreover, in plus of all auto-save requests failing with a small error,
the actual hard failure only occurs after filling all the form and
trying to submit it. Then the user is redirected to the sign-in page –
but all their changes are lost.
Instead, we now redirect to the sign-in page on the first 401 error
during the auto-save, let the user sign-in, and then redirect back to
the form.
Before, when autosaving a draft, removing a repetition row would
send `_destroy` inputs to the controller – but not remove the row
from the DOM. This led to the `_destroy` inputs being sent again
on the next autosave request, which made the controller raise
(because the row fields were already deleted before).
To fix this, we let the controller response remove the deleted
row(s) from the DOM.
Doing it using a controller response avoids the need to keep track
of operations on the Javascript side: the controller can easily
know which row was just deleted, and emit the relevant changes for
the DOM. This keeps the autosave requests robust: even if a request
is skipped (e.g. because of a network interruption), the next request
will still contain the relevant informations to succeed, and not let the
form in an unstable state.
Fix#5470
We have quite a lot of `Error reading file` errors when uploading files.
These errors are generated by ActiveStorage `file_checksum.js` component
but it eats the actual reason of errors.
(See https://github.com/rails/rails/blob/5-2-stable/activestorage/app/javascript/activestorage/file_checksum.js#L38)
We can't really override the class to generate better errors, as they
are deeply nested in ActiveStorage class hierarchy, and not exported to
external code.
Instead, we hook into the FileReader event handler, to insert a logger
when this error occur. The original event handler will also still be
called as usual.
This is intended to be temporary. The debug code will be removed once
we get a better idea of what is going on.
A DirectUpload may fail for several reasons, and return many types of
errors (string, xhr response, Error objects, etc).
For convenience, wrap all these errors in a FileUploadError object.
- It makes easier for clients of the Uploader class to handle errors;
- It allows to propagate the error code and failure responsability.