Skip to content

Fix unhandled promise rejection when prefetch request fails#1512

Closed
sskirby wants to merge 1 commit intohotwired:mainfrom
nulogy:fix-prefetch-cache-unhandled-rejection
Closed

Fix unhandled promise rejection when prefetch request fails#1512
sskirby wants to merge 1 commit intohotwired:mainfrom
nulogy:fix-prefetch-cache-unhandled-rejection

Conversation

@sskirby
Copy link
Copy Markdown

@sskirby sskirby commented Mar 3, 2026

PrefetchCache.putLater calls request.perform() without catching errors. FetchRequest.perform() re-throws non-AbortErrors after delegating.

In Safari, navigating away from a page while a prefetch is in-flight causes the browser to cancel the fetch with a TypeError instead of an AbortError. Since only AbortErrors are silently handled by FetchRequest, this surfaces as an unhandled rejection in Safari/iOS:

TypeError: Unhandled Promise Rejection: Load failed

Catch the rejection and evict the stale cache entry so that a fresh request is made when the user clicks the link.

This failure mode is also apparent in Chrome when prefetching while "Offline"

PrefetchCache.putLater calls request.perform() without catching errors.
FetchRequest.perform() re-throws non-AbortErrors after delegating.

In Safari, navigating away from a page while a prefetch is in-flight
causes the browser to cancel the fetch with a TypeError instead of an
AbortError. Since only AbortErrors are silently handled by FetchRequest,
this surfaces as an unhandled rejection in Safari/iOS:

  TypeError: Unhandled Promise Rejection: Load failed

Catch the rejection and evict the stale cache entry so that a fresh
request is made when the user clicks the link.
@sskirby
Copy link
Copy Markdown
Author

sskirby commented Mar 5, 2026

I am closing this PR because there are many more cases where reloading the page/navigating away will cause a "TypeError: Unhandled Promise Rejection: Load failed" in Safari. Most of which are very difficult to test for even if the project did have a suite of tests for Safari. In addition, the approach taken here has the risk of suppressing many other, unrelated, errors from error reporting tools like Sentry.

Another option would be to ignore TypeErrors with the message "Load failed" in the FetchRequest#perform method, but 1) this is Safari-specific and 2) Safari throws this same error for cases like CORS failures and SSL certificate errors which individual projects may not want suppressed.

@sskirby sskirby closed this Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant