diff --git a/lib/microwaveprop/workers/hrrr_fetch_worker.ex b/lib/microwaveprop/workers/hrrr_fetch_worker.ex index 66ebc897..98e33a86 100644 --- a/lib/microwaveprop/workers/hrrr_fetch_worker.ex +++ b/lib/microwaveprop/workers/hrrr_fetch_worker.ex @@ -56,28 +56,29 @@ defmodule Microwaveprop.Workers.HrrrFetchWorker do :ok {:error, reason} -> - if permanent_failure?(reason) do + if transient_failure?(reason) do + Logger.error("HRRR transient error for #{lat},#{lon} @ #{valid_time_str}: #{inspect(reason)}") + {:error, reason} + else Logger.warning("HRRR permanent failure for #{lat},#{lon} @ #{valid_time_str}: #{inspect(reason)}") {:cancel, reason} - else - Logger.error("HRRR fetch error for #{lat},#{lon} @ #{valid_time_str}: #{inspect(reason)}") - {:error, reason} end end end end - defp permanent_failure?("HRRR idx HTTP 404"), do: true - defp permanent_failure?("HRRR grib HTTP 404"), do: true - defp permanent_failure?("HRRR range request not supported"), do: true - defp permanent_failure?(:outside_grid), do: true - defp permanent_failure?("malformed section"), do: true - defp permanent_failure?("missing sections: " <> _), do: true - defp permanent_failure?("not a GRIB2 message"), do: true - defp permanent_failure?("unsupported GRIB edition " <> _), do: true - defp permanent_failure?("GRIB2 extraction failed: " <> _), do: true - defp permanent_failure?("GRIB2 complex packing decode failed: " <> _), do: true - defp permanent_failure?(_), do: false + # Only retry on transient network/server errors — everything else is permanent + defp transient_failure?(%{__exception__: true}), do: true + defp transient_failure?("HRRR idx HTTP " <> status), do: server_error?(status) + defp transient_failure?("HRRR grib HTTP " <> status), do: server_error?(status) + defp transient_failure?(_), do: false + + defp server_error?(status) do + case Integer.parse(status) do + {code, _} when code in [429, 500, 502, 503, 504] -> true + _ -> false + end + end defp maybe_add_derived_params(attrs, nil), do: attrs