Skip to content

Commit 640d073

Browse files
authored
Handle Phoenix LiveView exceptions (#9)
* Handle LiveView exceptions * LiveView dev script * Crash on handle params * Use latest Phoenix Playground commit * Handle throws and exits
1 parent 9f2f6fb commit 640d073

File tree

2 files changed

+124
-3
lines changed

2 files changed

+124
-3
lines changed

lib/error_tracker/integrations/phoenix.ex

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ defmodule ErrorTracker.Integrations.Phoenix do
1010

1111
alias ErrorTracker.Integrations.Plug, as: PlugIntegration
1212

13-
# https://hexdocs.pm/phoenix/Phoenix.Logger.html#module-instrumentation
1413
@events [
14+
# https://hexdocs.pm/phoenix/Phoenix.Logger.html#module-instrumentation
1515
[:phoenix, :router_dispatch, :start],
16-
[:phoenix, :router_dispatch, :exception]
16+
[:phoenix, :router_dispatch, :exception],
17+
# https://hexdocs.pm/phoenix_live_view/telemetry.html
18+
[:phoenix, :live_view, :mount, :start],
19+
[:phoenix, :live_view, :mount, :exception],
20+
[:phoenix, :live_view, :handle_params, :start],
21+
[:phoenix, :live_view, :handle_params, :exception],
22+
[:phoenix, :live_view, :handle_event, :start],
23+
[:phoenix, :live_view, :handle_event, :exception],
24+
[:phoenix, :live_view, :render, :exception]
1725
]
1826

1927
def attach do
@@ -36,6 +44,30 @@ defmodule ErrorTracker.Integrations.Phoenix do
3644
{reason, kind, stack}
3745
end
3846

39-
PlugIntegration.report_error(metadata.conn, {reason, kind}, stack)
47+
PlugIntegration.report_error(metadata.conn, {kind, reason}, stack)
48+
end
49+
50+
def handle_event([:phoenix, :live_view, :mount, :start], _, metadata, :no_config) do
51+
ErrorTracker.set_context(%{
52+
"live_view.view" => metadata.socket.view
53+
})
54+
end
55+
56+
def handle_event([:phoenix, :live_view, :handle_params, :start], _, metadata, :no_config) do
57+
ErrorTracker.set_context(%{
58+
"live_view.uri" => metadata.uri,
59+
"live_view.params" => metadata.params
60+
})
61+
end
62+
63+
def handle_event([:phoenix, :live_view, :handle_event, :start], _, metadata, :no_config) do
64+
ErrorTracker.set_context(%{
65+
"live_view.event" => metadata.event,
66+
"live_view.event_params" => metadata.params
67+
})
68+
end
69+
70+
def handle_event([:phoenix, :live_view, _action, :exception], _, metadata, :no_config) do
71+
ErrorTracker.report({metadata.kind, metadata.reason}, metadata.stacktrace)
4072
end
4173
end

live.exs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
Mix.install([
2+
{:phoenix_playground, github: "phoenix-playground/phoenix_playground", ref: "ee6da0fc3b141f78b9f967ce71a4fb015c6764a6"},
3+
{:error_tracker, path: "."}
4+
])
5+
6+
# Set up the repository for the Error Tracker
7+
defmodule ErrorTrackerDev.Repo do
8+
use Ecto.Repo, otp_app: :error_tracker, adapter: Ecto.Adapters.Postgres
9+
end
10+
11+
Application.put_env(:error_tracker, :repo, ErrorTrackerDev.Repo)
12+
Application.put_env(:error_tracker, :application, :error_tracker_dev)
13+
Application.put_env(:error_tracker, :prefix, "private")
14+
Application.put_env(:error_tracker, ErrorTrackerDev.Repo, url: "ecto://postgres:postgres@127.0.0.1/error_tracker_dev")
15+
16+
17+
# This migration will set up the database structure
18+
defmodule Migration0 do
19+
use Ecto.Migration
20+
21+
def up, do: ErrorTracker.Migrations.up(prefix: "private")
22+
def down, do: ErrorTracker.Migrations.down(prefix: "private")
23+
end
24+
25+
26+
defmodule DemoLive do
27+
use Phoenix.LiveView
28+
29+
def mount(params, _session, socket) do
30+
if params["crash"] == "mount" do
31+
raise "Crashing on mount"
32+
end
33+
34+
{:ok, assign(socket, count: 0)}
35+
end
36+
37+
def render(assigns) do
38+
if assigns.count == 5 do
39+
raise "Crash on render"
40+
end
41+
42+
~H"""
43+
<span><%= @count %></span>
44+
<button phx-click="inc">+</button>
45+
<button phx-click="dec">-</button>
46+
<button phx-click="error">Crash on handle_event</button>
47+
48+
<.link href="/?crash=mount">Crash on mount</.link>
49+
<.link patch="/?crash=handle_params">Crash on handle_params</.link>
50+
51+
<style type="text/css">
52+
body { padding: 1em; }
53+
</style>
54+
"""
55+
end
56+
57+
58+
def handle_event("inc", _params, socket) do
59+
{:noreply, assign(socket, count: socket.assigns.count + 1)}
60+
end
61+
62+
def handle_event("dec", _params, socket) do
63+
{:noreply, assign(socket, count: socket.assigns.count - 1)}
64+
end
65+
66+
def handle_event("error", _params, _socket) do
67+
raise "Crash on handle_event"
68+
end
69+
70+
def handle_params(params, _uri, socket) do
71+
if params["crash"] == "handle_params" do
72+
raise "Crash on handle_params"
73+
end
74+
{:noreply, socket}
75+
end
76+
end
77+
78+
79+
80+
PhoenixPlayground.start(live: DemoLive, child_specs: [ErrorTrackerDev.Repo])
81+
82+
83+
# Create the database if it does not exist and run migrations if needed
84+
_ = Ecto.Adapters.Postgres.storage_up(ErrorTrackerDev.Repo.config())
85+
86+
Ecto.Migrator.run(ErrorTrackerDev.Repo, [{0, Migration0}], :up,
87+
all: true,
88+
log_migrations_sql: :debug
89+
)

0 commit comments

Comments
 (0)