Two user-visible crashes in MapLive seen on prod pods today:
1. `:preload_forecast` handle_info timed out a Task.async_stream subtask
after 10 s and the `Enum.map(fn {:ok, h} -> h end)` match cascaded
the `:exit, :timeout` into the LiveView process, terminating the
session. Adds `on_timeout: :kill_task` and flat-maps only :ok
elements — a slow NFS forecast hour now drops from the preload
payload instead of killing the LV.
2. `LiveStash.stash/1` crashed with `** (ArgumentError) errors were
found at the given arguments: 2nd argument: not a valid match
specification` inside `:ets.select_replace/2` on OTP 28. The dep
(live_stash 0.2.0) has a latent bug against the tightened OTP 28
match-spec validator. Both call sites (MapLive.select_band,
SubmitLive.switch_tab) now route through a new
`MicrowavepropWeb.LiveStashGuard.stash/1` wrapper that rescues
ArgumentError, logs a warning, and returns the socket unchanged.
Stash is a convenience for reconnect state — failing it does not
need to kill the user's session.
Drop the guard module once the upstream match-spec fix lands.
34 lines
1,017 B
Elixir
34 lines
1,017 B
Elixir
defmodule MicrowavepropWeb.LiveStashGuard do
|
|
@moduledoc """
|
|
Tiny wrapper around `LiveStash.stash/1` that swallows the
|
|
`ArgumentError: not a valid match specification` crash LiveStash 0.2.0
|
|
raises under OTP 28.
|
|
|
|
The stash is a convenience for state persistence across reconnects;
|
|
a failure is not fatal to the user's session. We log and return the
|
|
socket unchanged instead of letting the LiveView process terminate
|
|
mid-`handle_event`.
|
|
|
|
Remove this module and inline `LiveStash.stash/1` calls once the
|
|
upstream match-spec fix lands in the `live_stash` hex package.
|
|
"""
|
|
|
|
alias Phoenix.LiveView.Socket
|
|
|
|
require Logger
|
|
|
|
@doc """
|
|
Best-effort wrapper around `LiveStash.stash/1`.
|
|
|
|
Returns the (possibly unchanged) socket no matter what the adapter
|
|
raises.
|
|
"""
|
|
@spec stash(Socket.t()) :: Socket.t()
|
|
def stash(socket) do
|
|
LiveStash.stash(socket)
|
|
rescue
|
|
e in ArgumentError ->
|
|
Logger.warning("LiveStashGuard: stash skipped (#{Exception.message(e)})")
|
|
socket
|
|
end
|
|
end
|