-
Notifications
You must be signed in to change notification settings - Fork 922
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
LiveView causes infinite reload loop in browser when an Ecto error is raised in connected handle_params #3379
Comments
The code that causes the reload is here: phoenix_live_view/lib/phoenix_live_view/channel.ex Lines 1181 to 1188 in a86683a
LV rescues the exception and sends a reload to trigger a new dead mount. This is consistent to what is described in https://hexdocs.pm/phoenix_live_view/error-handling.html#exceptions-during-connected-mount We should probably log the exception and not swallow it. I think we could also add a counter + jitter failsafe mechanism to phoenix_live_view/assets/js/phoenix_live_view/view.js Lines 790 to 794 in 2bb4564
|
@SteffenDE The docs that you pointed to do not seem to be consistent with the behavior shown here. There seems to be a difference between when an For example, when I use
which looks like it's from the live socket debugging functions, and the page waits several seconds (around 30 from my count, which is consistent with what I remember about LiveView's heartbeats) before a full page refresh. On the server, the crash is logged appropriately. When using the You can see that the exception is raised in the same place (within the connected From the code that you linked in Again, this behavior isn't consistent nor is it properly documented - the docs simply say that the LiveView will reload the page, but they fail to mention that an error underneath 500 will force the page into an infinite reloading loop, while an error above 500 will reload the page after around 30 seconds. |
There is a difference, yes, but in both cases LiveView triggers a redirect, hoping that the issue will happen again on the dead mount, causing the regular plug exception handling. Your analysis is right, "regular" exception trigger a "join crashed" and exceptions implementing Plug.Exception with an error code >= 400 < 500 are handled differently by sending a "reload" message. This behavior was introduced in 5bfe422, so @chrismccord may chime in to explain the reasons behind it. I assume it's to have quicker feedback on common errors like an So don't get me wrong. I'm not arguing that the current behavior is good, we should definitely prevent this from happening :) |
Not sure if this has been discussed before: but wouldn't error boundaries be a solution to this problem? In this way we could also isolate the errors better, instead of letting the whole page crash. |
Environment
Actual behavior
When an Ecto exception is raised within a
connected?(socket)
block inhandle_params
, LiveView goes into an infinite loop of full page browser reloads. The exception is not logged at all, and the reload loop is constant, not using any sort of backoff or retries, the entire browser page reloads over and over in an endless loop, with no logs.This seems to happen specifically on Ecto errors, I assume due to how Ecto errors may be handled within Phoenix and LiveView?
This is a reproduction using PhoenixPlayground, you can change the different modules to see different behaviors.
Expected behavior
Other exception types don't cause this infinite full page reload loop (as can be seen if you try using the
NormalExceptionShowsCrash
module in the playground script above), they instead seem to retry mounting on a retry with some sort of timer (console logs show an error that the join failed and eventually there is a retry). Additionally, app logs show the crash and error reason.I would expect all exceptions to behave similarly, no full page reloads in an infinite loop, and crash logs being shown so that we can know why the app is in an infinite reload loop.
The text was updated successfully, but these errors were encountered: