Packages

TaskBunny job failure backend that reports the error to Sentry

Current section

Files

Jump to
task_bunny_sentry lib task_bunny_sentry.ex
Raw

lib/task_bunny_sentry.ex

defmodule TaskBunnySentry do
@moduledoc """
A TaskBunny failure backend that reports to Sentry.
"""
use TaskBunny.FailureBackend
alias TaskBunny.JobError
require Logger
defexception [:message]
def report_job_error(error = %JobError{error_type: :exception}) do
report_error(error.exception, error.stacktrace, error)
end
def report_job_error(error = %JobError{error_type: :exit}) do
%TaskBunnySentry{message: "Unexpected exit signal"}
|> report_error(error.stacktrace, error)
end
def report_job_error(error = %JobError{error_type: :return_value}) do
%TaskBunnySentry{message: "Unexpected return value"}
|> report_error(original_stacktrace(Process.info(self(), :current_stacktrace)), error)
end
def report_job_error(error = %JobError{error_type: :timeout}) do
%TaskBunnySentry{message: "Timeout error"}
|> report_error(original_stacktrace(Process.info(self(), :current_stacktrace)), error)
end
def report_job_error(error = %JobError{}) do
%TaskBunnySentry{message: "Unknown error"}
|> report_error(original_stacktrace(Process.info(self(), :current_stacktrace)), error)
end
defp original_stacktrace(stacktrace) do
chunks = stacktrace |> elem(1) |> Enum.chunk_by(&(elem(&1, 0) == TaskBunnySentry))
Enum.at(chunks, 1) ++ Enum.at(chunks, 2)
end
defp report_error(naked_exception, stacktrace, wrapped_error) do
Logger.error "TaskBunny.JobError: #{inspect(terse_error(wrapped_error))}"
Sentry.capture_exception(
naked_exception,
[
stacktrace: stacktrace,
extra: %{
meta: inspect(wrapped_error.meta),
job: wrapped_error.job,
job_payload: wrapped_error.payload,
pid: inspect(wrapped_error.pid),
exit: wrapped_error.reason,
return_value: inspect(wrapped_error.return_value)
}
]
)
end
defp terse_error(error) do
Map.drop(error, [:job, :payload, :__struct__, :stacktrace, :reason, :meta, :pid, :raw_body])
end
end