Current section

Files

Jump to
honeylixir lib transmission_sender.ex
Raw

lib/transmission_sender.ex

defmodule Honeylixir.TransmissionSender do
@unknown_error "unknown error"
@moduledoc """
Typically invoked as a Task, handles sending the `Honeylixir.Event` batches to
the `Honeylixir.Client` and adding responses to the queue.
"""
@doc """
Does the actual passoff to the `Honeylixir.Client` for sending.
Responses are sent via `:telemetry.execute/3`.
"""
@spec send_batch(list(Honeylixir.Event.t())) :: :ok
def send_batch(events) do
case Honeylixir.Client.send_batch(events) do
{:ok, response, duration} ->
responses = Jason.decode!(response.body)
process_event_responses(events, responses, duration)
{:failure, response, duration} ->
error_body = error_response_body(Jason.decode(response.body))
responses =
Enum.map(events, fn _ ->
%{"status" => response.status_code, "error" => error_body}
end)
process_event_responses(events, responses, duration)
{:error, %HTTPoison.Error{}, duration} ->
Enum.each(events, fn event ->
:telemetry.execute(
Honeylixir.event_send_telemetry_key(),
%{},
%{response: Honeylixir.Response.http_error_response(event, duration)}
)
end)
:ok
end
end
defp error_response_body({:ok, body}) when is_map(body),
do: Map.get(body, "error", @unknown_error)
defp error_response_body({:ok, body}), do: body
defp error_response_body({:error, %Jason.DecodeError{data: data}}) when data == "",
do: @unknown_error
defp error_response_body({:error, %Jason.DecodeError{data: data}}), do: data
defp process_event_responses([], [], _), do: :ok
defp process_event_responses([event | rest], [%{"status" => 202} | response_rest], duration) do
:telemetry.execute(
Honeylixir.event_send_telemetry_key(),
%{},
%{response: Honeylixir.Response.success_response(event, duration, 202)}
)
process_event_responses(rest, response_rest, duration)
end
defp process_event_responses(
[event | rest],
[%{"error" => error_body, "status" => status_code} | response_rest],
duration
) do
:telemetry.execute(
Honeylixir.event_send_telemetry_key(),
%{},
%{response: Honeylixir.Response.failure_response(event, duration, status_code, error_body)}
)
process_event_responses(rest, response_rest, duration)
end
end