fix(weather): tolerate stale map_bounds from /map → /weather navigation
/map's PropagationMap hook pushes `map_bounds` on every moveend/zoomend. When a user live-navigates from /map to /weather, an in-flight bounds push can land on the new WeatherMapLive (the same LV channel survives the navigation), and WeatherMapLive's `handle_event/3` had no clause for it — the LV process crashed with FunctionClauseError, taking the user's session down. WeatherMapLive doesn't need viewport bounds — the /weather/cells HTTP endpoint reads them off the URL the client builds — so the safe fix is a no-op handler. Tested.
This commit is contained in:
parent
b14c87126c
commit
1f8765f757
2 changed files with 30 additions and 0 deletions
|
|
@ -232,6 +232,14 @@ defmodule MicrowavepropWeb.WeatherMapLive do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# `/map`'s PropagationMap hook pushes `map_bounds` on moveend/zoomend.
|
||||||
|
# When a user navigates /map → /weather, an in-flight bounds push from
|
||||||
|
# the old hook can land on the new WeatherMapLive (LV reuses sockets
|
||||||
|
# across live navigation). WeatherMapLive doesn't need bounds — the
|
||||||
|
# /weather/cells HTTP endpoint computes them client-side — so swallow
|
||||||
|
# the event instead of crashing the LV process.
|
||||||
|
def handle_event("map_bounds", _params, socket), do: {:noreply, socket}
|
||||||
|
|
||||||
def handle_event("point_detail", %{"lat" => lat, "lon" => lon}, socket) do
|
def handle_event("point_detail", %{"lat" => lat, "lon" => lon}, socket) do
|
||||||
detail =
|
detail =
|
||||||
if socket.assigns.valid_time do
|
if socket.assigns.valid_time do
|
||||||
|
|
|
||||||
|
|
@ -319,4 +319,26 @@ defmodule MicrowavepropWeb.WeatherMapLiveTest do
|
||||||
assert html =~ ~s(data-selected-layer=)
|
assert html =~ ~s(data-selected-layer=)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "stale client events" do
|
||||||
|
test "ignores `map_bounds` from a stale browser tab without crashing", %{conn: conn} do
|
||||||
|
# A user can navigate /map → /weather while the propagation map's
|
||||||
|
# JS hook still has a queued moveend → pushEvent("map_bounds", …)
|
||||||
|
# in flight. The WeatherMapLive doesn't need viewport bounds (it
|
||||||
|
# fetches /weather/cells over HTTP using the *client* viewport),
|
||||||
|
# but it MUST tolerate the rogue event instead of crashing the
|
||||||
|
# LV process.
|
||||||
|
{:ok, lv, _html} = live(conn, ~p"/weather")
|
||||||
|
|
||||||
|
bounds = %{
|
||||||
|
"south" => 32.57,
|
||||||
|
"north" => 33.62,
|
||||||
|
"west" => -97.37,
|
||||||
|
"east" => -95.76
|
||||||
|
}
|
||||||
|
|
||||||
|
html = render_hook(lv, "map_bounds", bounds)
|
||||||
|
assert is_binary(html)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue