I have a <turbo-frame>
and when I submit form it gets replaced. So far it is great and magical.
But if my server returns 500 (I have an unexpected error) Turbo replaces my frame with empty frame and writes ts to console: Response has no matching <turbo-frame id="some-frame"> element
.
Is there any way to render response in this case? I want to show user that my site borked and render generic error message that my server side created.
5 Likes
I have been wondering this same question. @AdamLuczynski Did you find a solution? I would love for others to chime in
I think this regards to the general question: how to intercept a response in a turbo frame? In my case, I wanted to intercept the 401 unauthorized. This is my solution .
1 Like
I was able to catch and process a 500 error using the event.detail.success
value of the submit-end
event. Here’s a video demonstrating:
tleish
December 3, 2021, 2:02pm
#5
You may be interested in following the progress of this MR:
hotwired:main
← seanpdoyle:missing-frame-in-response
opened 08:31PM - 14 Nov 21 UTC
Closes [hotwired/turbo#432][]
Follow-up to [hotwired/turbo#94][]
Follow-up to … [hotwired/turbo#31][]
When a response from _within_ a frame is missing a matching frame, fire
the `turbo:frame-missing` event.
There is an existing [contract][] that dictates a request from within a
frame stays within a frame.
However, if an application is interested in reacting to a response
without a frame, dispatch a `turbo:frame-missing` event. The event's
`target` is the `FrameElement`, and the `detail` contains the response
instance under the `fetchResponse:` key.
Event listeners for `turbo:frame-missing` can invoke call
`event.preventDefault()`, then call `Turbo.visit(event.detail.fetchResponse)`.
The call to `Turbo.visit(fetchResponse)` also
accepts `Partial<VisitOptions>` as an optional argument:
```js
addEventListener("turbo:frame-missing", (event) => {
const { target, detail: { fetchResponse } } = event
// the details of `shouldRedirectOnMissingFrame(element: FrameElement, fetchResponse: FetchResponse)`
// are up to the application to decide
if (shouldRedirectOnMissingFrame(target, fetchResponse)) {
event.preventDefault()
Turbo.visit(event.detail.fetchResponse)
}
})
```
The event listener is also a good opportunity to change the
`<turbo-frame>` element itself to prevent future missing responses.
For example, if the reason the frame is missing is access (an expired
session, for example), the call to `Turbo.visit()` can be made with `{ action:
"replace" }` to remove the current page from Turbo's page history.
Similarly, if the reason for the missing frame is particular to the page
referenced by the element's `[src]` attribute, this is an opportunity to
change that attribute (calling `event.target.removeAttribute("src")`,
for example) before navigating away so that re-visiting the page by
navigating backward in the Browser's history doesn't automatically load
the frame and re-trigger another `turbo:frame-missing` event.
[contract]: https://github.com/hotwired/turbo/issues/94#issuecomment-756968205
[hotwired/turbo#432]: https://github.com/hotwired/turbo/issues/432
[hotwired/turbo#94]: https://github.com/hotwired/turbo/issues/94
[hotwired/turbo#31]: https://github.com/hotwired/turbo/issues/31
Treat response `turbo-frame[disabled]` as missing
===
When a response body has a `turbo-frame` element with an `[id]` that
matches the requesting frame, ignore it if it's `[disabled]`.