Last active
July 27, 2022 08:26
-
-
Save ruslandoga/9bb8c0a27f8ffd7661d34b8957c9d9ac to your computer and use it in GitHub Desktop.
A particular sentry + finch setup that results in sentry entering a possibly infinite error loop with some possible workarounds.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Mix.install([:sentry, :finch, :jason]) | |
defmodule Sentry.FinchClient do | |
@moduledoc false | |
# adapts https://github.com/getsentry/sentry-elixir/blob/master/lib/sentry/hackney_client.ex | |
@behaviour Sentry.HTTPClient | |
@finch_name S.Finch | |
@impl true | |
def child_spec do | |
child_spec = {Finch, name: @finch_name, pools: %{default: [size: 1, count: 1]}} | |
Supervisor.child_spec(child_spec, []) | |
end | |
@impl true | |
def post(url, headers, body) do | |
req = Finch.build(:post, url, headers, body) | |
case Finch.request(req, @finch_name, receive_timeout: 5000) do | |
{:ok, %Finch.Response{status: status, body: body, headers: headers}} -> | |
{:ok, status, headers, body} | |
{:error, _reason} = failure -> | |
failure | |
end | |
end | |
end | |
Application.put_all_env( | |
sentry: [ | |
client: Sentry.FinchClient, | |
environment_name: :test, | |
included_environments: [:test], | |
dsn: System.fetch_env!("SENTRY_DSN") | |
] | |
) | |
Application.put_env(:logger, Sentry.LoggerBackend, capture_log_messages: true) | |
Logger.add_backend(Sentry.LoggerBackend) | |
:ok = Application.ensure_started(:sentry) | |
Enum.each(1..1000, fn i -> Sentry.capture_message("event #{i}") end) | |
receive do | |
:never -> :ok | |
end |
Possible fix #3
Sentry package could add try/catch around calling the custom client. Pseudocode
Current
# Somewhere in sentry package
if custom_client do
custom_client.post(url, headers, body) # If this throws, things go bad
end
Proposed
# Somewhere in sentry package
if custom_client do
try do
custom_client.post(url, headers, body)
catch
e -> {:error, e}
end
end
This way, no matter what the client does, the error loop is prevented. We should ask - is there any reason for the Sentry package to report an exception that happened in the custom client?
I don't think so, and I think the error should be suppressed. If the client throws, it means sentry cannot report the error. It seems absurd to me to report an error that happened during reporting an error.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Possible fix #2
Use http2 protocol for which finch doesn't use nimble_pool and returns mint's error tuples in a similar scenario instead of raising:
Which prevents sentry task from crashing and instead makes it retry the request.