Skip to content

Commit f2d45e4

Browse files
committed
Fix crash on error detail page when using MySQL/MariaDB
Instead of using `{:array, :string}` for the `:breadcrumbs` field in `ErrorTracker.Occurrence` we use a new custom field type `ErrorTracker.Types.StringArray`. It uses `Jason` to decode arrays when retrieving data from MySQL/MariaDB. Therefore it works very similarly to the `:array` type but without crashing on retrieval. This fix does not make a schema migration necessary. An additional test module `ErrorTracker.StoreFetchTest` was implemented to avoid regreessions in the future. Fixes #150.
1 parent 99c3fb2 commit f2d45e4

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

lib/error_tracker/schemas/occurrence.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule ErrorTracker.Occurrence do
1818
field :reason, :string
1919

2020
field :context, :map
21-
field :breadcrumbs, {:array, :string}
21+
field :breadcrumbs, ErrorTracker.Types.StringArray
2222

2323
embeds_one :stacktrace, ErrorTracker.Stacktrace
2424
belongs_to :error, ErrorTracker.Error
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
defmodule ErrorTracker.Types.StringArray do
2+
@moduledoc """
3+
Custom Ecto type for lists.
4+
5+
The built-in `:array` type is not properly implemented for the Ecto adapter `Ecto.Adapters.MyXQL`.
6+
Therefore we can not use it and have to impelement our own.
7+
"""
8+
use Ecto.Type
9+
10+
def type, do: {:array, :string}
11+
12+
def cast(list) when is_list(list) do
13+
{:ok, list}
14+
end
15+
16+
def cast(_), do: :error
17+
18+
def load(list) when is_binary(list) do
19+
Jason.decode(list)
20+
end
21+
22+
def load(list) when is_nil(list) do
23+
[]
24+
end
25+
26+
def load(list), do: {:ok, list}
27+
28+
def dump(list) when is_list(list) do
29+
ErrorTracker.Repo.with_adapter(fn
30+
:mysql -> Jason.encode(list)
31+
_ -> {:ok, list}
32+
end)
33+
end
34+
35+
def dump(_), do: :error
36+
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
defmodule ErrorTracker.StoreFetchTest do
2+
@moduledoc """
3+
Test if simple store-retrieve operations are successful.
4+
5+
This is necessary, because some Ecto adapters like `Ecto.Adapters.MyXQL` may successfully store a field, but crash on retrieval.
6+
"""
7+
use ErrorTracker.Test.Case
8+
9+
test "after reporting an error its occurrence should be retrievable from DB" do
10+
assert %ErrorTracker.Occurrence{id: occurrence_id} =
11+
report_error(fn -> raise "BOOM" end)
12+
13+
assert %ErrorTracker.Occurrence{} = repo().get!(ErrorTracker.Occurrence, occurrence_id)
14+
end
15+
end

0 commit comments

Comments
 (0)