More error handling, retry automatically on disconnected

This commit is contained in:
Shadowfacts 2024-04-07 10:37:46 -04:00
parent 257ea3e47e
commit fdf59f660a
3 changed files with 39 additions and 7 deletions

View File

@ -8,8 +8,20 @@ defmodule TuskerPush.Apns do
with {:ok, body} <- Jason.encode(payload, pretty_print: false),
req <- make_request(registration, body),
{:ok, resp} <- Finch.request(req, TuskerPush.Finch) do
handle_response(resp, registration.apns_environment)
handle_response(resp, registration, payload)
else
{:error, %Finch.Error{reason: :connection_closed}} ->
Logger.warning("Apns Finch connection_closed, retrying")
__MODULE__.send(registration, payload)
{:error, %Finch.Error{reason: :disconnected}} ->
Logger.warning("Apns Finch disconnected, retrying")
__MODULE__.send(registration, payload)
{:error, %Mint.TransportError{reason: :closed}} ->
Logger.warning("Apns Mint transport closed, retrying")
__MODULE__.send(registration, payload)
{:error, reason} ->
{:error, reason}
end
@ -36,10 +48,10 @@ defmodule TuskerPush.Apns do
)
end
@spec handle_response(Finch.Response.t(), :development | :production) :: :ok | {:error, term()}
@spec handle_response(Finch.Response.t(), Registration.t(), Map.t()) :: :ok | {:error, term()}
defp handle_response(resp, env) do
maybe_log_unique_id(resp, env)
defp handle_response(resp, registration, payload) do
maybe_log_unique_id(resp, registration.apns_environment)
if resp.status in 200..299 do
:ok
@ -53,11 +65,22 @@ defmodule TuskerPush.Apns do
resp.body
end
Logger.error("Received #{resp.status} with #{info}")
case {resp.status, info} do
{403, %{reason: "ExpiredProviderToken"}} ->
Logger.warning("Expired provider token, retrying")
__MODULE__.send(registration, payload)
{410, %{reason: "Unregistered"}} ->
Logger.warning("Device token unregistered")
{:error, :device_token_unregistered}
_ ->
Logger.error("Received #{resp.status} with #{inspect(info)}")
{:error, "unexpected status #{resp.status}"}
end
end
end
@spec maybe_log_unique_id(Finch.Response.t(), :development | :production) :: :ok

View File

@ -2,6 +2,8 @@ defmodule TuskerPush.Forwarder do
alias TuskerPush.Apns
alias TuskerPush.Registration
require Logger
@spec forward(Registration.t(), binary(), String.t(), String.t()) :: :ok | {:error, term()}
def forward(%Registration{push_version: 1} = registration, body, salt, key) do
payload = %{
@ -18,6 +20,8 @@ defmodule TuskerPush.Forwarder do
"v" => 1
}
Logger.debug("Sending #{inspect(payload)}")
Apns.send(registration, payload)
end
end

View File

@ -20,7 +20,7 @@ defmodule TuskerPushWeb.PushController do
{:expired, registration} ->
TuskerPush.unregister(registration)
send_resp(conn, 400, "unregistered")
send_resp(conn, 400, "expired")
{:encoding, encoding} ->
Logger.warning("Unexpected encoding: #{inspect(encoding)}")
@ -42,6 +42,11 @@ defmodule TuskerPushWeb.PushController do
Logger.warning("Missing key")
send_resp(conn, 400, "missing key")
{:forward, {:error, :device_token_unregistered}} ->
Logger.debug("APNS device token unregistered, removing registration")
TuskerPush.unregister(id)
send_resp(conn, 400, "apns unregistered")
{:forward, {:error, reason}} ->
Logger.error("Sending notification: #{inspect(reason)}")
send_resp(conn, 500, "failed to send")