Current section

Files

Jump to
sentry lib sentry client_error.ex
Raw

lib/sentry/client_error.ex

defmodule Sentry.ClientError do
@moduledoc """
An exception struct that represents an error returned by Sentry when
reporting an error or a message.
This struct is designed to manage and handle errors originating from operations
in the Sentry client. The `:reason` field contains the cause of the error
as an atom or tuple (see `t:reason/0`).
To raise instances of this exception, you can use `raise/1`. When crafting
formatted error messages for purposes such as logging or presentation, consider
leveraging `Exception.message/1`.
"""
@moduledoc since: "10.7.0"
@doc """
The exception struct for a Sentry error.
"""
defexception [:reason, :http_response]
@typedoc """
The type for a Sentry error exception.
"""
@type t :: %__MODULE__{
reason: reason(),
http_response:
nil | {status :: 100..599, headers :: [{String.t(), String.t()}], body :: binary()}
}
@typedoc """
The reason for a Sentry error exception.
"""
@type reason() ::
:too_many_retries
| :server_error
| {:invalid_json, Exception.t()}
| {:request_failure, reason :: :inet.posix() | term()}
| {Exception.kind(), reason :: term(), Exception.stacktrace()}
@doc false
@spec new(reason()) :: t
def new(reason) do
%__MODULE__{reason: reason}
end
@doc false
@spec server_error(status :: 100..599, headers :: [{String.t(), String.t()}], body :: binary()) ::
t
def server_error(status, headers, body) do
%__MODULE__{reason: :server_error, http_response: {status, headers, body}}
end
@impl true
def message(%__MODULE__{reason: reason, http_response: http_response}) do
"Sentry failed to report event: #{format(reason, http_response)}"
end
defp format(:server_error, {status, headers, body}) do
"""
the Sentry server responded with an error, the details are below.
HTTP Status: #{status}
Response Headers: #{inspect(headers)}
Response Body: #{inspect(body)}
"""
end
defp format(reason, nil) do
format(reason)
end
defp format(:too_many_retries) do
"Sentry responded with status 429 - Too Many Requests and the SDK exhausted the configured retries"
end
defp format({:invalid_json, reason}) do
formatted =
if is_exception(reason) do
Exception.message(reason)
else
inspect(reason)
end
"the Sentry SDK could not encode the event to JSON: #{formatted}"
end
defp format({:request_failure, reason}) do
"there was a request failure: #{format_request_failure(reason)}"
end
defp format({kind, data, stacktrace}) do
"""
there was an unexpected error:
#{Exception.format(kind, data, stacktrace)}\
"""
end
defp format_request_failure(reason) when is_binary(reason) do
reason
end
defp format_request_failure(reason) when is_atom(reason) do
case :inet.format_error(reason) do
~c"unknown POSIX error" -> inspect(reason)
formatted -> List.to_string(formatted)
end
end
defp format_request_failure(reason) do
inspect(reason)
end
end