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

Provide event to handle turbo-frame hitting a NetworkError when fetching #462

Closed
romaricpascal opened this issue Nov 22, 2021 · 1 comment · Fixed by #640
Closed

Provide event to handle turbo-frame hitting a NetworkError when fetching #462

romaricpascal opened this issue Nov 22, 2021 · 1 comment · Fixed by #640

Comments

@romaricpascal
Copy link

At the moment, if a turbo-frame cannot make its request to the server due to a network issue, there is no way to provide feedback to users as the error gets only logged to the console and not surfaced anywhere. No before-fetch-response gets triggered as, well..., there was indeed no response.

It'd be great if the frame would dispatch a turbo:fetch-error event (or similarly named) to let the page add some rendering.

For now, this can be achieved through the following, but requires some very far reaching overriding:

const frame = document.createElement("turbo-frame");
const controllerPrototype = Object.getPrototypeOf(frame.delegate);
const originalRequestErrored = controllerPrototype.requestErrored;
controllerPrototype.requestErrored = function (request, error) {
  console.log('Network error', this.element, 'Dispatching event');
  this.element.dispatchEvent(new CustomEvent('turbo:fetch-error', {
    bubbles: true,
    cancelable: true,
    detail: {request,error}
  }));
  return originalRequestErrored.apply(this, arguments);
};

To harmonize error handling, it may also be worth dispatching this event when the response is not a success, though that could be easily achieved by library users through:

document.addEventListener('turbo:before-fetch-response', (event) => {
  if (!event.detail.fetchResponse.response.ok) {
    event.target.dispatchEvent(new CustomEvent('turbo:fetch-error', {
      bubbles: true,
      cancelable: true,
      detail: event.detail
    }))
  }
});

I'm not familiar if this would translate to Turbo drive as well, I'd guess there must be some place it needs to handle fetch errors too.

@corporealfunk
Copy link

corporealfunk commented Dec 16, 2021

I agree that this would be useful. It would be nice to be able access the fact that the network failed when we set the src attribute on a frame. Homegonizing errors would be nice too instead of having to listen for submit-end and also before-fetch-response.

To further homogenize the error handling, so that turbo:fetch-error will also trigger when a form fetch request encounters a NetworkError:

// we want to catch turbo-frame network errors on all frames:
const frame = document.createElement('turbo-frame');
const controllerPrototype = Object.getPrototypeOf(frame.delegate);
const originalRequestErrored = controllerPrototype.requestErrored;

controllerPrototype.requestErrored = function (request, error) {
  this.element.dispatchEvent(new CustomEvent('turbo:fetch-error', {
    bubbles: true,
    cancelable: true,
    detail: { request, error, success: false },
  }));

  return originalRequestErrored.apply(this, arguments);
};

const checkForFetchError = (event) => {
  if (!event.detail.fetchResponse.response.ok) {
    event.target.dispatchEvent(new CustomEvent('turbo:fetch-error', {
      bubbles: true,
      cancelable: true,
      detail: event.detail,
    }));
  }
};

const checkForNetworkError = (event) => {
  if (!event.detail.fetchResponse && event.detail.success === false) {
    event.target.dispatchEvent(new CustomEvent('turbo:fetch-error', {
      bubbles: true,
      cancelable: true,
      detail: event.detail,
    }));
  }
};

// check for error states in the response from the server:
document.addEventListener('turbo:before-fetch-response', checkForFetchError);

// check for error states when the server doesn't even respond:
document.addEventListener('turbo:submit-end', checkForNetworkError);

srt32 added a commit to srt32/turbo that referenced this issue Jul 20, 2022
closes hotwired#462

This PR adds a new event called `turbo:fetch-error` that dispatches
when a form or frame fetch request errors.

This event will let developers respond appropriately when a fetch request
fails due network errors (such as on flaky wifi).

At the moment, if a frame navigation fetch request fails due to a network
error an error is thrown so https://github.com/hotwired/turbo/blob/2d5cdda4c030658da21965cb20d2885ca7c3e127/src/http/fetch_request.ts#L107 never runs
and therefore the `turbo:before-fetch-response` event is not dispatched.
srt32 added a commit to srt32/turbo that referenced this issue Jul 20, 2022
closes hotwired#462

This PR adds a new event called `turbo:fetch-error` that dispatches
when a form or frame fetch request errors.

This event will let developers respond appropriately when a fetch request
fails due network errors (such as on flaky wifi).

At the moment, if a frame navigation fetch request fails due to a network
error an error is thrown so https://github.com/hotwired/turbo/blob/2d5cdda4c030658da21965cb20d2885ca7c3e127/src/http/fetch_request.ts#L107 never runs
and therefore the `turbo:before-fetch-response` event is not dispatched.
srt32 added a commit to srt32/turbo that referenced this issue Jul 20, 2022
closes hotwired#462

This PR adds a new event called `turbo:fetch-error` that dispatches
when a form or frame fetch request errors.

This event will let developers respond appropriately when a fetch request
fails due network errors (such as on flaky wifi).

At the moment, if a frame navigation fetch request fails due to a network
error an error is thrown so https://github.com/hotwired/turbo/blob/2d5cdda4c030658da21965cb20d2885ca7c3e127/src/http/fetch_request.ts#L107 never runs
and therefore the `turbo:before-fetch-response` event is not dispatched.
@dhh dhh closed this as completed in #640 Aug 3, 2022
dhh pushed a commit that referenced this issue Aug 3, 2022
…640)

* Add turbo:fetch-error event on frame and form network errors

closes #462

This PR adds a new event called `turbo:fetch-error` that dispatches
when a form or frame fetch request errors.

This event will let developers respond appropriately when a fetch request
fails due network errors (such as on flaky wifi).

At the moment, if a frame navigation fetch request fails due to a network
error an error is thrown so https://github.com/hotwired/turbo/blob/2d5cdda4c030658da21965cb20d2885ca7c3e127/src/http/fetch_request.ts#L107 never runs
and therefore the `turbo:before-fetch-response` event is not dispatched.

* Update src/core/frames/frame_controller.ts

Co-authored-by: Keith Cirkel <[email protected]>

* Update src/core/drive/form_submission.ts

Co-authored-by: Keith Cirkel <[email protected]>

* Add spec

* Get browser name right

* Fetch project name properly

* Use page.context()

* remove timeout on offline

* Use first page to reduce go to calls

* Use tabs again since behavior is different when using turbo-action

* use broader event assertion

* Update event name and export type

* add new event to test helper

* Limit recursion in the test helper

* skip the details obj instead of limiting recursion

Co-authored-by: Keith Cirkel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants