Packages
appsignal
1.10.10
2.17.4
2.17.3
2.17.2
2.17.1
2.17.0
2.16.0
2.15.11
2.15.10
2.15.9
2.15.8
2.15.7
2.15.6
2.15.5
2.15.4
2.15.3
2.15.2
2.15.1
2.15.0
2.14.1
2.14.0
2.13.4
2.13.3
2.13.2
2.13.1
2.13.0
2.12.3
2.12.2
2.12.1
2.12.0
2.11.0
2.10.2
2.10.1
2.10.0
2.9.2
2.9.1
2.9.0
2.8.3
2.8.2
2.8.1
2.8.0
2.7.13
2.7.12
2.7.11
2.7.10
2.7.9
2.7.8
2.7.7
2.7.6
2.7.5
2.7.4
2.7.3
2.7.2
2.7.1
2.7.0
2.7.0-beta.1
2.6.1
2.6.0
2.5.3
2.5.2
2.5.1
2.5.0
2.4.3
2.4.2
2.4.1
2.4.0
2.3.1
2.3.0
2.2.19
2.2.18
2.2.17
2.2.16
2.2.15
2.2.14
2.2.13
2.2.12
retired
2.2.11
2.2.10
2.2.9
2.2.8
2.2.7
2.2.6
2.2.5
2.2.4
2.2.3
2.2.2
2.2.1
2.2.0
2.1.15
2.1.14
2.1.13
2.1.12
2.1.11
2.1.10
2.1.9
2.1.8
2.1.7
2.1.7-beta.1
2.1.6
2.1.5
2.1.4
2.1.3
2.1.2
2.1.1
2.1.0
2.0.8
2.0.7
2.0.6
2.0.6-beta.1
2.0.5
retired
2.0.4
retired
2.0.3
retired
2.0.2
retired
2.0.1
retired
2.0.0
retired
2.0.0-beta.11
2.0.0-beta.10
2.0.0-beta.9
2.0.0-beta.8
2.0.0-beta.7
2.0.0-beta.6
2.0.0-beta.5
2.0.0-beta.4
2.0.0-beta.3
2.0.0-beta.2
2.0.0-beta.1
2.0.0-alpha.7
2.0.0-alpha.6
2.0.0-alpha.5
2.0.0-alpha.4
2.0.0-alpha.3
2.0.0-alpha.2
2.0.0-alpha.1
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
1.13.0
1.13.0-beta.2
1.13.0-beta.1
1.12.1
1.12.0
1.12.0-beta.3
1.12.0-beta.2
1.12.0-beta.1
1.11.8
1.11.7
1.11.6
1.11.5
1.11.4
1.11.3
1.11.2
1.11.1
1.11.0
1.11.0-beta.1
1.10.13
1.10.12
1.10.11
1.10.10
1.10.9
1.10.8
1.10.7
1.10.6
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.4
1.9.3
1.9.2
1.9.1
1.9.1-beta.1
1.9.0
1.9.0-beta.1
1.9.0-alpha.1
1.8.2
1.8.1
1.8.1-beta.2
1.8.1-beta.1
1.8.0
1.7.2
1.7.1
1.7.0
1.7.0-beta.2
1.7.0-beta.1
1.7.0-alpha.4
1.7.0-alpha.3
1.7.0-alpha.2
1.7.0-alpha.1
1.6.7
1.6.6
1.6.6-beta.2
1.6.6-beta.1
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.6.0-beta.1
1.6.0-alpha.1
1.5.1
1.5.0
1.5.0-beta.2
1.5.0-beta.1
1.4.11-beta.1
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-alpha.1
1.3.6
1.3.6-beta.1
1.3.5
1.3.4
1.3.4-beta.1
1.3.3
1.3.2
1.3.1
1.3.0
1.3.0-beta.3
1.3.0-beta.2
1.3.0-beta.1
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc.1
0.13.0
0.12.3
0.12.2
0.12.1
0.12.0
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.2
0.9.1
0.9.0
0.8.0
0.7.1
0.7.0
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Collects error and performance data from your Elixir applications and sends it to AppSignal
Current section
Files
Jump to
Current section
Files
lib/appsignal/error_handler.ex
defmodule Appsignal.ErrorHandler do
@moduledoc """
Error handler which sends all crash reports to the AppSignal backend.
When you add `:appsignal` to your application's dependencies, this
error logger will automatically be installed. All processes that are
supervised, like GenServers, Tasks, Agents, Supervisored will be
monitored for crashes. In the case of a crash, the AppSignal error
handler collects error information and sends it to the backend.
"""
alias Appsignal.{Backtrace, Error}
require Logger
@transaction Application.get_env(
:appsignal,
:appsignal_transaction,
Appsignal.Transaction
)
@spec handle_error(
Appsignal.Transaction.t() | pid() | any(),
any(),
Exception.stacktrace(),
map()
) :: :ok
def handle_error(pid_or_transaction, error, stack, conn \\ %{})
def handle_error(pid, error, stack, conn) when is_pid(pid) do
pid
|> @transaction.lookup_or_create_transaction
|> handle_error(error, stack, conn)
end
def handle_error(%Appsignal.Transaction{} = transaction, error, stack, conn) do
{exception, stacktrace} = Error.normalize(error, stack)
do_handle_error(transaction, exception, stacktrace, conn)
end
def handle_error(_transaction, _error, _stack, _conn), do: :ok
@spec do_handle_error(Appsignal.Transaction.t(), Exception.t(), list(String.t()), map()) :: :ok
defp do_handle_error(_, %{plug_status: status}, _, _) when status < 500, do: :ok
defp do_handle_error(transaction, exception, stack, conn) do
{reason, message} = Appsignal.Error.metadata(exception)
backtrace = Backtrace.from_stacktrace(stack)
@transaction.set_error(transaction, reason, message, backtrace)
if @transaction.finish(transaction) == :sample do
@transaction.set_request_metadata(transaction, conn)
end
@transaction.complete(transaction)
end
def submit_transaction(transaction, reason, message, stack, metadata, conn \\ nil)
def submit_transaction(transaction, reason, message, stack, metadata, nil) do
@transaction.set_error(transaction, reason, message, stack)
@transaction.set_meta_data(transaction, metadata)
@transaction.finish(transaction)
@transaction.complete(transaction)
Logger.debug(fn ->
"Submitting #{inspect(transaction)}: #{message}"
end)
transaction
end
if Appsignal.plug?() do
def submit_transaction(transaction, reason, message, stack, metadata, conn) do
if conn do
@transaction.set_request_metadata(transaction, conn)
end
submit_transaction(transaction, reason, message, stack, metadata)
end
end
@doc false
@spec match_event(term) :: {pid, term, String.t(), list, %{}} | :nomatch
def match_event({:error_report, _gleader, {origin, :crash_report, [report | _]}})
when is_list(report) do
{_kind, error, stack} = report[:error_info]
{origin, error, stack, %{}}
rescue
exception ->
Logger.warn(fn ->
"""
AppSignal: Failed to match error report: #{Exception.message(exception)}
#{inspect(report[:error_info])}
"""
end)
:nomatch
end
def match_event(_event) do
:nomatch
end
@doc false
@deprecated "Use Appsignal.ErrorLoggerHandler.init/1 instead."
def init(state) do
Appsignal.ErrorLoggerHandler.init(state)
end
@doc false
@deprecated "Use Appsignal.ErrorLoggerHandler.handle_event/2 instead."
def handle_event(event, state) do
Appsignal.ErrorLoggerHandler.handle_event(event, state)
end
@doc false
@deprecated "Use Appsignal.ErrorLoggerHandler.handle_info/2 instead."
def handle_info(info, state) do
Appsignal.ErrorLoggerHandler.handle_info(info, state)
end
@doc false
@deprecated "Use Appsignal.Backtrace.from_stacktrace/1 instead."
def format_stack(stacktrace) do
Backtrace.from_stacktrace(stacktrace)
end
@deprecated "Use Appsignal.Error.metadata/1 instead."
def extract_reason_and_message(any, prefix) do
{exception, _} = Error.normalize(any, [])
{name, message} = Error.metadata(exception)
{name, prefixed(prefix, message)}
end
defp prefixed(nil, msg), do: msg
defp prefixed("", msg), do: msg
defp prefixed(pre, msg), do: pre <> ": " <> msg
@pid_or_ref_regex ~r/\<(\d+\.)+\d+\>/
@deprecated "Use Appsignal.Error.metadata/1 instead."
def normalize_reason(reason) do
Regex.replace(@pid_or_ref_regex, reason, "<...>")
end
end