Skip to content

Commit b6f6df0

Browse files
solnicCopilot
andcommitted
fix(logger): retain auto-handler on invalid user config for Sentry.LoggerHandler
Co-authored-by: Copilot <copilot@github.com>
1 parent 8777322 commit b6f6df0

2 files changed

Lines changed: 34 additions & 17 deletions

File tree

lib/sentry/logger_handler.ex

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -263,18 +263,6 @@ defmodule Sentry.LoggerHandler do
263263
@doc false
264264
@spec adding_handler(:logger.handler_config()) :: {:ok, :logger.handler_config()}
265265
def adding_handler(config) do
266-
# If a user explicitly registers their own Sentry.LoggerHandler (i.e., not the
267-
# auto-registered :sentry_log_handler), remove the auto-registered one to prevent
268-
# duplicate log capture. We spawn a separate process to do the removal because
269-
# adding_handler/1 is called from within the logger gen_server process, and calling
270-
# :logger.remove_handler/1 directly would deadlock.
271-
if config.id != :sentry_log_handler do
272-
_ = spawn(fn -> :logger.remove_handler(:sentry_log_handler) end)
273-
:ok
274-
else
275-
:ok
276-
end
277-
278266
# The :config key may not be here.
279267
sentry_config = Map.get(config, :config, %{})
280268

@@ -294,12 +282,26 @@ defmodule Sentry.LoggerHandler do
294282

295283
config = Map.put(config, :config, handler_config)
296284

297-
if rate_limiting_config = config.config.rate_limiting do
298-
_ = RateLimiter.start_under_sentry_supervisor(config.id, rate_limiting_config)
299-
{:ok, config}
300-
else
301-
{:ok, config}
285+
result =
286+
if rate_limiting_config = config.config.rate_limiting do
287+
_ = RateLimiter.start_under_sentry_supervisor(config.id, rate_limiting_config)
288+
{:ok, config}
289+
else
290+
{:ok, config}
291+
end
292+
293+
# If a user explicitly registers their own Sentry.LoggerHandler (i.e., not the
294+
# auto-registered :sentry_log_handler), remove the auto-registered one to prevent
295+
# duplicate log capture. We do this after all validation so that if config is
296+
# invalid (and adding_handler raises), the auto-handler stays active. We spawn a
297+
# separate process because adding_handler/1 is called from within the logger
298+
# gen_server process, and calling :logger.remove_handler/1 directly would deadlock.
299+
if config.id != :sentry_log_handler do
300+
_ = spawn(fn -> :logger.remove_handler(:sentry_log_handler) end)
301+
:ok
302302
end
303+
304+
result
303305
end
304306

305307
# Callback for :logger handlers

test/sentry/application_test.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,21 @@ defmodule Sentry.ApplicationTest do
115115
:logger.get_handler_config(:sentry_log_handler)
116116
end
117117

118+
test "keeps auto-handler when a user adds a Sentry.LoggerHandler with invalid config" do
119+
restart_sentry_with(dsn: "https://public@sentry.example.com/1", enable_logs: true)
120+
assert {:ok, _} = :logger.get_handler_config(:sentry_log_handler)
121+
122+
user_handler = :"user_sentry_handler_#{System.unique_integer([:positive])}"
123+
124+
assert {:error, _reason} =
125+
:logger.add_handler(user_handler, Sentry.LoggerHandler, %{
126+
config: %{sync_threshold: 10, discard_threshold: 20}
127+
})
128+
129+
assert {:ok, _} = :logger.get_handler_config(:sentry_log_handler)
130+
assert {:error, {:not_found, ^user_handler}} = :logger.get_handler_config(user_handler)
131+
end
132+
118133
test "auto-handler captures logs to the buffer" do
119134
restart_sentry_with(dsn: "https://public@sentry.example.com/1", enable_logs: true)
120135

0 commit comments

Comments
 (0)