Skip to content

Commit 8dfdfab

Browse files
committed
no logging from logger and client error refactor
1 parent 575c984 commit 8dfdfab

File tree

5 files changed

+65
-54
lines changed

5 files changed

+65
-54
lines changed

lib/sentry/client.ex

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ defmodule Sentry.Client do
5656
Attempts to send the event to the Sentry API up to 4 times with exponential backoff.
5757
5858
The event is dropped if it all retries fail.
59+
Errors will be logged unless the source is the Sentry.LoggerBackend, which can deadlock by logging within a logger.
5960
6061
### Options
6162
* `:result` - Allows specifying how the result should be returned. Options include `:sync`, `:none`, and `:async`. `:sync` will make the API call synchronously, and return `{:ok, event_id}` if successful. `:none` sends the event from an unlinked child process under `Sentry.TaskSupervisor` and will return `{:ok, ""}` regardless of the result. `:async` will start an unlinked task and return a tuple of `{:ok, Task.t}` on success where the Task can be awaited upon to receive the result asynchronously. When used in an OTP behaviour like GenServer, the task will send a message that needs to be matched with `GenServer.handle_info/2`. See `Task.Supervisor.async_nolink/2` for more information. `:async` is the default.
@@ -65,6 +66,7 @@ defmodule Sentry.Client do
6566
def send_event(%Event{} = event, opts \\ []) do
6667
result = Keyword.get(opts, :result, :async)
6768
sample_rate = Keyword.get(opts, :sample_rate) || Config.sample_rate()
69+
should_log = event.event_source != :logger
6870

6971
event = maybe_call_before_send_event(event)
7072

@@ -76,22 +78,27 @@ defmodule Sentry.Client do
7678
:unsampled
7779

7880
{%Event{}, true} ->
79-
encode_and_send(event, result)
81+
encode_and_send(event, result, should_log)
8082
end
8183
end
8284

83-
@spec encode_and_send(Event.t(), result()) :: send_event_result()
84-
defp encode_and_send(event, result) do
85+
@spec encode_and_send(Event.t(), result(), boolean()) :: send_event_result()
86+
defp encode_and_send(event, result, should_log) do
8587
json_library = Config.json_library()
8688

8789
render_event(event)
8890
|> json_library.encode()
8991
|> case do
9092
{:ok, body} ->
91-
do_send_event(event, body, result)
93+
result = do_send_event(event, body, result)
94+
95+
if should_log do
96+
maybe_log_result(result)
97+
end
98+
99+
result
92100

93101
{:error, error} ->
94-
# log_api_error("Unable to encode Sentry error - #{inspect(error)}")
95102
{:error, {:invalid_json, error}}
96103
end
97104
end
@@ -152,18 +159,12 @@ defmodule Sentry.Client do
152159
when current_attempt > @max_attempts,
153160
do: {:error, {:request_failure, last_error}}
154161

155-
defp try_request(url, headers, {event, body}, current_attempt) do
162+
defp try_request(url, headers, {event, body}, {current_attempt, _last_error}) do
156163
case request(url, headers, body) do
157164
{:ok, id} ->
158165
{:ok, id}
159166

160167
{:error, error} ->
161-
# if(current_attempt == 1) do
162-
# log_api_error("Event ID: #{event.event_id} - #{inspect(error)} - #{body}")
163-
# else
164-
# log_api_error("Event ID: #{event.event_id} - #{inspect(error)}")
165-
# end
166-
167168
if current_attempt < @max_attempts, do: sleep(current_attempt)
168169

169170
try_request(url, headers, {event, body}, {current_attempt + 1, error})
@@ -224,14 +225,6 @@ defmodule Sentry.Client do
224225
"Sentry " <> query
225226
end
226227

227-
@spec authorization_headers(String.t(), String.t()) :: list({String.t(), String.t()})
228-
defp authorization_headers(public_key, secret_key) do
229-
[
230-
{"User-Agent", @sentry_client},
231-
{"X-Sentry-Auth", authorization_header(public_key, secret_key)}
232-
]
233-
end
234-
235228
@doc """
236229
Get a Sentry DSN which is simply a URI.
237230
@@ -251,7 +244,6 @@ defmodule Sentry.Client do
251244
{endpoint, public_key, secret_key}
252245
else
253246
_ ->
254-
# log_api_error("Cannot send event because of invalid DSN")
255247
{:error, :invalid_dsn}
256248
end
257249
end
@@ -337,6 +329,43 @@ defmodule Sentry.Client do
337329
end
338330
end
339331

332+
def maybe_log_result(result) do
333+
message =
334+
case result do
335+
{:error, :invalid_dsn} ->
336+
"Cannot send Sentry event because of invalid DSN"
337+
338+
{:error, {:invalid_json, error}} ->
339+
"Unable to encode JSON Sentry error - #{inspect(error)}"
340+
341+
{:error, {:request_failure, last_error}} ->
342+
"Error in HTTP Request to Sentry - #{inspect(last_error)}"
343+
344+
{:error, error} ->
345+
inspect(error)
346+
347+
_ ->
348+
nil
349+
end
350+
351+
if message != nil do
352+
Logger.log(
353+
Config.log_level(),
354+
fn ->
355+
["Failed to send Sentry event.", message]
356+
end
357+
)
358+
end
359+
end
360+
361+
@spec authorization_headers(String.t(), String.t()) :: list({String.t(), String.t()})
362+
defp authorization_headers(public_key, secret_key) do
363+
[
364+
{"User-Agent", @sentry_client},
365+
{"X-Sentry-Auth", authorization_header(public_key, secret_key)}
366+
]
367+
end
368+
340369
defp keys_from_userinfo(userinfo) do
341370
case String.split(userinfo, ":", parts: 2) do
342371
[public, secret] -> [public, secret]
@@ -345,7 +374,8 @@ defmodule Sentry.Client do
345374
end
346375
end
347376

348-
@spec get_headers_and_endpoint :: {String.t(), String.t(), String.t()} | {:error, :invalid_dsn}
377+
@spec get_headers_and_endpoint ::
378+
{String.t(), list({String.t(), String.t()})} | {:error, :invalid_dsn}
349379
defp get_headers_and_endpoint do
350380
case get_dsn() do
351381
{endpoint, public_key, secret_key} ->
@@ -356,15 +386,6 @@ defmodule Sentry.Client do
356386
end
357387
end
358388

359-
defp log_api_error(body) do
360-
# Logger.log(
361-
# Config.log_level(),
362-
# fn ->
363-
# ["Failed to send Sentry event.", inspect(body)]
364-
# end
365-
# )
366-
end
367-
368389
@spec sleep(pos_integer()) :: :ok
369390
defp sleep(1), do: :timer.sleep(2000)
370391
defp sleep(2), do: :timer.sleep(4000)

test/client_test.exs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,41 +44,31 @@ defmodule Sentry.ClientTest do
4444
test "errors on bad public keys" do
4545
modify_env(:sentry, dsn: "https://app.getsentry.com/1")
4646

47-
capture_log(fn ->
48-
assert :error = Sentry.Client.get_dsn()
49-
end)
47+
assert {:error, :invalid_dsn} = Sentry.Client.get_dsn()
5048
end
5149

5250
test "errors on non-integer project_id" do
5351
modify_env(:sentry, dsn: "https://public:[email protected]/Mitchell")
5452

55-
capture_log(fn ->
56-
assert :error = Sentry.Client.get_dsn()
57-
end)
53+
assert {:error, :invalid_dsn} = Sentry.Client.get_dsn()
5854
end
5955

6056
test "errors on no project_id" do
6157
modify_env(:sentry, dsn: "https://public:[email protected]")
6258

63-
capture_log(fn ->
64-
assert :error = Sentry.Client.get_dsn()
65-
end)
59+
assert {:error, :invalid_dsn} = Sentry.Client.get_dsn()
6660
end
6761

6862
test "errors on nil dsn" do
6963
modify_env(:sentry, dsn: nil)
7064

71-
capture_log(fn ->
72-
assert :error = Sentry.Client.get_dsn()
73-
end)
65+
assert {:error, :invalid_dsn} = Sentry.Client.get_dsn()
7466
end
7567

7668
test "errors on atom dsn" do
7769
modify_env(:sentry, dsn: :error)
7870

79-
capture_log(fn ->
80-
assert :error = Sentry.Client.get_dsn()
81-
end)
71+
assert {:error, :invalid_dsn} = Sentry.Client.get_dsn()
8272
end
8373

8474
test "logs api errors" do
@@ -114,7 +104,7 @@ defmodule Sentry.ClientTest do
114104
unencodable_event = %Sentry.Event{message: "error", level: {:a, :b}}
115105

116106
capture_log(fn ->
117-
assert :error = Sentry.Client.send_event(unencodable_event)
107+
assert {:error, {:invalid_json, _}} = Sentry.Client.send_event(unencodable_event)
118108
end)
119109
end
120110

test/mix/sentry.send_test_event_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ defmodule Mix.Tasks.Sentry.SendTestEventTest do
5555
"""
5656
end
5757

58-
test "handles :error when Sentry server is failing" do
58+
test "handles error when Sentry server is failing" do
5959
bypass = Bypass.open()
6060

6161
Bypass.expect(bypass, fn conn ->
@@ -78,7 +78,7 @@ defmodule Mix.Tasks.Sentry.SendTestEventTest do
7878
hackney_opts: [recv_timeout: 50]
7979
8080
Sending test event...
81-
Error sending event!
81+
Error sending event: "Received 500 from Sentry server: "
8282
"""
8383
end) =~ "Failed to send Sentry event"
8484
end

test/sentry_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ defmodule SentryTest do
5555
dsn: "http://public:secret@localhost:#{bypass.port}/1"
5656
)
5757

58-
assert capture_log(fn ->
59-
assert :error = Sentry.capture_message("error", [])
60-
end) =~ "Failed to send Sentry event"
58+
capture_log(fn ->
59+
assert {:error, _} = Sentry.capture_message("error", [])
60+
end)
6161

6262
Bypass.pass(bypass)
6363
end

test/support/test_client.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ defmodule Sentry.TestClient do
2626
end
2727
)
2828

29-
:error
29+
{:error, error}
3030
end
3131

3232
{:error, error} ->
@@ -35,7 +35,7 @@ defmodule Sentry.TestClient do
3535
"Error sending in Sentry.TestClient: #{inspect(error)}"
3636
)
3737

38-
:error
38+
{:error, error}
3939
end
4040
end
4141
end

0 commit comments

Comments
 (0)