diff --git a/lib/microwaveprop/application.ex b/lib/microwaveprop/application.ex index 596af17f..8a7a89ed 100644 --- a/lib/microwaveprop/application.ex +++ b/lib/microwaveprop/application.ex @@ -5,6 +5,8 @@ defmodule Microwaveprop.Application do use Application + require Logger + @build_timestamp DateTime.utc_now() @impl true @@ -66,7 +68,15 @@ defmodule Microwaveprop.Application do # already set, so re-running on every boot is safe (and useful: any # users registered while the worker module was unavailable get # 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) if Application.get_env(:microwaveprop, :load_ml_model, false) do diff --git a/lib/microwaveprop/weather/gefs_client.ex b/lib/microwaveprop/weather/gefs_client.ex index 87264054..6393e913 100644 --- a/lib/microwaveprop/weather/gefs_client.ex +++ b/lib/microwaveprop/weather/gefs_client.ex @@ -19,6 +19,8 @@ defmodule Microwaveprop.Weather.GefsClient do derivation (GEFS pgrb2a publishes RH rather than Td). """ + require Logger + @base_url "https://nomads.ncep.noaa.gov/pub/data/nccf/com/gens/prod" @run_hours [0, 6, 12, 18] @@ -273,8 +275,13 @@ defmodule Microwaveprop.Weather.GefsClient do timeout: 120_000 ) |> Enum.map(fn - {:ok, result} -> result - {:exit, reason} -> {:error, reason} + {:ok, result} -> + result + + {:exit, reason} -> + Logger.error("GEFS grib range download crashed: url=#{url} reason=#{inspect(reason)}") + + {:error, reason} end) case Enum.find(results, &match?({:error, _}, &1)) do diff --git a/lib/microwaveprop_web/live/path_live.ex b/lib/microwaveprop_web/live/path_live.ex index 9dce28f6..30b52c46 100644 --- a/lib/microwaveprop_web/live/path_live.ex +++ b/lib/microwaveprop_web/live/path_live.ex @@ -284,7 +284,11 @@ defmodule MicrowavepropWeb.PathLive do %{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 end @@ -346,8 +350,15 @@ defmodule MicrowavepropWeb.PathLive do # Richardson so turbulent duct readings don't inflate the score. native_duct = case Weather.nearest_native_duct_info(midlat, midlon, now) do - {:ok, info} -> info - {:error, _} -> %{best_duct_band_ghz: nil, bulk_richardson: nil} + {:ok, info} -> + 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 # Build conditions and score @@ -474,8 +485,18 @@ defmodule MicrowavepropWeb.PathLive do defp profile_grid_for(valid_time) do case ProfilesFile.read(valid_time) do - {:ok, grid} -> grid - _ -> nil + {:ok, grid} -> + 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 diff --git a/lib/microwaveprop_web/live/rover_live.ex b/lib/microwaveprop_web/live/rover_live.ex index ff4aa5af..01eb28dd 100644 --- a/lib/microwaveprop_web/live/rover_live.ex +++ b/lib/microwaveprop_web/live/rover_live.ex @@ -395,7 +395,9 @@ defmodule MicrowavepropWeb.RoverLive do {:ok, stations} -> {:noreply, socket |> assign_stations(stations) |> sync_url()} - {:error, _} -> + {:error, reason} -> + Logger.error("RoverLive station mutation failed: id=#{inspect(id)} reason=#{inspect(reason)}") + {:noreply, socket} end end