fix: log every silent error path so failures surface in k8s logs
Sweep of remaining swallowed-error sites flagged by an audit pass:
- weather/gefs_client.ex: byte-range download task exits log url + reason
before being surfaced as {:error, _} (matches the HRRR fix).
- live/path_live.ex: terrain-profile load failure, native-duct lookup
failure, and ProfilesFile.read failure now log warnings with path
endpoints / midpoint / valid_time. Previously rendered a degraded
result silently.
- live/rover_live.ex: station-mutation {:error, _} now logs id + reason
instead of dropping into {:noreply, socket}.
- application.ex: the boot-time backfill_missing_home_qth Task.start is
now wrapped in try/rescue. A DB issue at boot would have crashed the
task silently (no Logger handler attached pre-Logger crash format).
This commit is contained in:
parent
301935f8c1
commit
f26fbafc29
4 changed files with 49 additions and 9 deletions
|
|
@ -5,6 +5,8 @@ defmodule Microwaveprop.Application do
|
||||||
|
|
||||||
use Application
|
use Application
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
@build_timestamp DateTime.utc_now()
|
@build_timestamp DateTime.utc_now()
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
@ -66,7 +68,15 @@ defmodule Microwaveprop.Application do
|
||||||
# already set, so re-running on every boot is safe (and useful: any
|
# already set, so re-running on every boot is safe (and useful: any
|
||||||
# users registered while the worker module was unavailable get
|
# users registered while the worker module was unavailable get
|
||||||
# picked up the next time the pod restarts).
|
# picked up the next time the pod restarts).
|
||||||
{:ok, _pid} = Task.start(fn -> Microwaveprop.Accounts.backfill_missing_home_qth() end)
|
{:ok, _pid} =
|
||||||
|
Task.start(fn ->
|
||||||
|
try do
|
||||||
|
Microwaveprop.Accounts.backfill_missing_home_qth()
|
||||||
|
rescue
|
||||||
|
e ->
|
||||||
|
Logger.error("Application: backfill_missing_home_qth crashed: #{Exception.format(:error, e, __STACKTRACE__)}")
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
# Load ML model in dev/test only (Nx/Axon not compiled for prod)
|
# Load ML model in dev/test only (Nx/Axon not compiled for prod)
|
||||||
if Application.get_env(:microwaveprop, :load_ml_model, false) do
|
if Application.get_env(:microwaveprop, :load_ml_model, false) do
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ defmodule Microwaveprop.Weather.GefsClient do
|
||||||
derivation (GEFS pgrb2a publishes RH rather than Td).
|
derivation (GEFS pgrb2a publishes RH rather than Td).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
@base_url "https://nomads.ncep.noaa.gov/pub/data/nccf/com/gens/prod"
|
@base_url "https://nomads.ncep.noaa.gov/pub/data/nccf/com/gens/prod"
|
||||||
|
|
||||||
@run_hours [0, 6, 12, 18]
|
@run_hours [0, 6, 12, 18]
|
||||||
|
|
@ -273,8 +275,13 @@ defmodule Microwaveprop.Weather.GefsClient do
|
||||||
timeout: 120_000
|
timeout: 120_000
|
||||||
)
|
)
|
||||||
|> Enum.map(fn
|
|> Enum.map(fn
|
||||||
{:ok, result} -> result
|
{:ok, result} ->
|
||||||
{:exit, reason} -> {:error, reason}
|
result
|
||||||
|
|
||||||
|
{:exit, reason} ->
|
||||||
|
Logger.error("GEFS grib range download crashed: url=#{url} reason=#{inspect(reason)}")
|
||||||
|
|
||||||
|
{:error, reason}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
case Enum.find(results, &match?({:error, _}, &1)) do
|
case Enum.find(results, &match?({:error, _}, &1)) do
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,11 @@ defmodule MicrowavepropWeb.PathLive do
|
||||||
|
|
||||||
%{profile: profile, analysis: analysis}
|
%{profile: profile, analysis: analysis}
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, reason} ->
|
||||||
|
Logger.warning(
|
||||||
|
"PathLive terrain profile load failed: src=#{src.lat},#{src.lon} dst=#{dst.lat},#{dst.lon} reason=#{inspect(reason)}"
|
||||||
|
)
|
||||||
|
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -346,8 +350,15 @@ defmodule MicrowavepropWeb.PathLive do
|
||||||
# Richardson so turbulent duct readings don't inflate the score.
|
# Richardson so turbulent duct readings don't inflate the score.
|
||||||
native_duct =
|
native_duct =
|
||||||
case Weather.nearest_native_duct_info(midlat, midlon, now) do
|
case Weather.nearest_native_duct_info(midlat, midlon, now) do
|
||||||
{:ok, info} -> info
|
{:ok, info} ->
|
||||||
{:error, _} -> %{best_duct_band_ghz: nil, bulk_richardson: nil}
|
info
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
Logger.warning(
|
||||||
|
"PathLive nearest_native_duct_info failed: midpoint=#{midlat},#{midlon} reason=#{inspect(reason)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
%{best_duct_band_ghz: nil, bulk_richardson: nil}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Build conditions and score
|
# Build conditions and score
|
||||||
|
|
@ -474,8 +485,18 @@ defmodule MicrowavepropWeb.PathLive do
|
||||||
|
|
||||||
defp profile_grid_for(valid_time) do
|
defp profile_grid_for(valid_time) do
|
||||||
case ProfilesFile.read(valid_time) do
|
case ProfilesFile.read(valid_time) do
|
||||||
{:ok, grid} -> grid
|
{:ok, grid} ->
|
||||||
_ -> nil
|
grid
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
Logger.warning("PathLive ProfilesFile.read failed: valid_time=#{inspect(valid_time)} reason=#{inspect(reason)}")
|
||||||
|
|
||||||
|
nil
|
||||||
|
|
||||||
|
other ->
|
||||||
|
Logger.warning("PathLive ProfilesFile.read unexpected: valid_time=#{inspect(valid_time)} got=#{inspect(other)}")
|
||||||
|
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -395,7 +395,9 @@ defmodule MicrowavepropWeb.RoverLive do
|
||||||
{:ok, stations} ->
|
{:ok, stations} ->
|
||||||
{:noreply, socket |> assign_stations(stations) |> sync_url()}
|
{:noreply, socket |> assign_stations(stations) |> sync_url()}
|
||||||
|
|
||||||
{:error, _} ->
|
{:error, reason} ->
|
||||||
|
Logger.error("RoverLive station mutation failed: id=#{inspect(id)} reason=#{inspect(reason)}")
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue