Skip to content

Commit 8f541c5

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

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-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: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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) do
23+
{:ok, list}
24+
end
25+
26+
def dump(list) when is_list(list) do
27+
ErrorTracker.Repo.with_adapter(fn
28+
:mysql -> Jason.encode(list)
29+
_ -> {:ok, list}
30+
end)
31+
end
32+
33+
def dump(_), do: :error
34+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
defmodule ErrorTracker.StoreFetchTest do
2+
@moduledoc """
3+
Test if simple store-retrieve operations are successful.
4+
This is necessary, because some Ecto adapter like `Ecto.Adapters.MyXQL` may successfully store a field, but crash on retrieval.
5+
"""
6+
use ErrorTracker.Test.Case
7+
8+
test "after reporting an error its occurrences should be retrievable from DB" do
9+
assert %ErrorTracker.Occurrence{id: occurrence_id} =
10+
report_error(fn -> raise "BOOM" end)
11+
12+
assert %ErrorTracker.Occurrence{} = repo().get!(ErrorTracker.Occurrence, occurrence_id)
13+
end
14+
end

0 commit comments

Comments
 (0)