Skip to content

Commit d79919f

Browse files
committed
Actually fix empty frames in stacktraces
See #787.
1 parent 211a29f commit d79919f

File tree

2 files changed

+61
-20
lines changed

2 files changed

+61
-20
lines changed

lib/sentry/client.ex

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -287,24 +287,27 @@ defmodule Sentry.Client do
287287
defp render_exception(%Interfaces.Exception{} = exception) do
288288
exception
289289
|> Map.from_struct()
290-
|> render_stacktrace()
290+
|> render_or_delete_stacktrace()
291291
|> update_if_present(:mechanism, &Map.from_struct/1)
292292
end
293293

294294
defp render_thread(%Interfaces.Thread{} = thread) do
295295
thread
296296
|> Map.from_struct()
297-
|> render_stacktrace()
297+
|> render_or_delete_stacktrace()
298298
end
299299

300-
defp render_stacktrace(map) do
301-
case map do
302-
%{stacktrace: %{frames: %Interfaces.Stacktrace{frames: [_ | _]} = stacktrace}} ->
303-
%{stacktrace | frames: Enum.map(stacktrace.frames, &Map.from_struct/1)}
300+
# If there are frames, render the stacktrace, otherwise delete it altogether from the map.
301+
defp render_or_delete_stacktrace(
302+
%{stacktrace: %Interfaces.Stacktrace{frames: [_ | _]}} = exception_or_thread
303+
) do
304+
exception_or_thread
305+
|> Map.update!(:stacktrace, &Map.from_struct/1)
306+
|> update_in([:stacktrace, :frames, Access.all()], &Map.from_struct/1)
307+
end
304308

305-
map_without_stacktrace ->
306-
Map.delete(map_without_stacktrace, :stacktrace)
307-
end
309+
defp render_or_delete_stacktrace(exception_or_thread) do
310+
Map.delete(exception_or_thread, :stacktrace)
308311
end
309312

310313
defp remove_nils(map) when is_map(map) do
@@ -362,11 +365,8 @@ defmodule Sentry.Client do
362365

363366
defp update_if_present(map, key, fun) do
364367
case Map.pop(map, key) do
365-
{nil, _} ->
366-
map
367-
368-
{value, map} ->
369-
Map.put(map, key, fun.(value))
368+
{nil, _} -> map
369+
{value, map} -> Map.put(map, key, fun.(value))
370370
end
371371
end
372372

test/sentry/client_test.exs

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,22 +84,63 @@ defmodule Sentry.ClientTest do
8484
:code.purge(RaisingJSONClient)
8585
end
8686

87-
test "renders threads with stacktrace property deleted if :frames field set to nil if empty" do
87+
test "renders stacktrace for threads" do
88+
event =
89+
Event.create_event(
90+
message: "Stacktrace for threads",
91+
stacktrace: [
92+
{Kernel, :apply, 3, [file: "lib/kernel.ex", line: 1]},
93+
{URI, :new!, 1, [file: "lib/uri.ex", line: 2]}
94+
]
95+
)
96+
97+
assert %{threads: [thread]} = Client.render_event(event)
98+
99+
refute is_struct(thread.stacktrace),
100+
":stacktrace shouldn't be a struct, got: #{inspect(thread.stacktrace)}"
101+
102+
assert [
103+
%{module: URI, function: "URI.new!/1", filename: "lib/uri.ex", lineno: 2},
104+
%{module: Kernel, function: "Kernel.apply/3", filename: "lib/kernel.ex", lineno: 1}
105+
] = thread.stacktrace.frames
106+
end
107+
108+
test "renders threads with :stacktrace property deleted if :frames field set to nil if empty" do
88109
event =
89110
Event.create_event(message: "No frames in stacktrace", stacktrace: [])
90111

91-
client = Client.render_event(event)
112+
assert %{threads: [thread]} = Client.render_event(event)
113+
refute Map.has_key?(thread, :stacktrace)
114+
end
115+
116+
test "renders stacktrace for exceptions" do
117+
event =
118+
Event.transform_exception(
119+
%RuntimeError{message: "foo"},
120+
stacktrace: [
121+
{Kernel, :apply, 3, [file: "lib/kernel.ex", line: 1]},
122+
{URI, :new!, 1, [file: "lib/uri.ex", line: 2]}
123+
]
124+
)
125+
126+
assert %{exception: [exception]} = Client.render_event(event)
127+
128+
refute is_struct(exception.stacktrace),
129+
":stacktrace shouldn't be a struct, got: #{inspect(exception.stacktrace)}"
92130

93-
assert is_nil(get_in(client.threads, [Access.at(0), :stacktrace]))
131+
assert [
132+
%{module: URI, function: "URI.new!/1", filename: "lib/uri.ex", lineno: 2},
133+
%{module: Kernel, function: "Kernel.apply/3", filename: "lib/kernel.ex", lineno: 1}
134+
] = exception.stacktrace.frames
94135
end
95136

96-
test "renders exception with stacktrace property deleted if :frames field set to nil if empty" do
137+
test "renders exception with :stacktrace property deleted if :frames field set to nil if empty" do
97138
event =
98139
Event.transform_exception(%RuntimeError{message: "foo"}, stacktrace: [])
99140

100-
client = Client.render_event(event)
141+
assert %{exception: [exception]} = Client.render_event(event)
101142

102-
assert is_nil(get_in(client.exception, [Access.at(0), :stacktrace]))
143+
refute Map.has_key?(exception, :stacktrace)
103144
end
104145

105146
test "removes non-payload fields" do

0 commit comments

Comments
 (0)