Skip to content

Commit

Permalink
Add turbo:fetch-error event on frame and form network errors
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
srt32 committed Jul 20, 2022
1 parent 25f7e7d commit 8ab07c2
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/core/drive/form_submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FetchResponse } from "../../http/fetch_response"
import { expandURL } from "../url"
import { dispatch, getMetaContent } from "../../util"
import { StreamMessage } from "../streams/stream_message"
import { TurboFetchErrorEvent } from "../session"

export interface FormSubmissionDelegate {
formSubmissionStarted(formSubmission: FormSubmission): void
Expand Down Expand Up @@ -199,6 +200,11 @@ export class FormSubmission {

requestErrored(request: FetchRequest, error: Error) {
this.result = { success: false, error }
dispatch<TurboFetchErrorEvent>("turbo:fetch-error", {
target: this.formElement,
detail: { request, error },
cancelable: true,
})
this.delegate.formSubmissionErrored(this, error)
}

Expand Down
7 changes: 6 additions & 1 deletion src/core/frames/frame_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { FrameRenderer } from "./frame_renderer"
import { session } from "../index"
import { isAction, Action } from "../types"
import { VisitOptions } from "../drive/visit"
import { TurboBeforeFrameRenderEvent } from "../session"
import { TurboBeforeFrameRenderEvent, TurboFetchErrorEvent } from "../session"

export class FrameController
implements
Expand Down Expand Up @@ -241,6 +241,11 @@ export class FrameController

requestErrored(request: FetchRequest, error: Error) {
console.error(error)
dispatch<TurboFetchErrorEvent>("turbo:fetch-error", {
target: this.element,
detail: { request, error },
cancelable: true,
})
this.resolveVisitPromise()
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { FrameElement } from "../elements/frame_element"
import { FrameViewRenderOptions } from "./frames/frame_view"
import { FetchResponse } from "../http/fetch_response"
import { Preloader, PreloaderDelegate } from "./drive/preloader"
import { FetchRequest } from "../http/fetch_request"

export type TimingData = unknown
export type TurboBeforeCacheEvent = CustomEvent
Expand All @@ -29,6 +30,7 @@ export type TurboBeforeVisitEvent = CustomEvent<{ url: string }>
export type TurboClickEvent = CustomEvent<{ url: string; originalEvent: MouseEvent }>
export type TurboFrameLoadEvent = CustomEvent
export type TurboBeforeFrameRenderEvent = CustomEvent<{ newFrame: FrameElement } & FrameViewRenderOptions>
export type TurboFetchErrorEvent = CustomEvent<{ request: FetchRequest; error: Error }>
export type TurboFrameRenderEvent = CustomEvent<{ fetchResponse: FetchResponse }>
export type TurboLoadEvent = CustomEvent<{ url: string; timing: TimingData }>
export type TurboRenderEvent = CustomEvent
Expand Down

0 comments on commit 8ab07c2

Please sign in to comment.