diff --git a/lib/error_tracker.ex b/lib/error_tracker.ex index 6511316..092f4a7 100644 --- a/lib/error_tracker.ex +++ b/lib/error_tracker.ex @@ -280,14 +280,18 @@ defmodule ErrorTracker do defp normalize_exception({kind, ex}, stacktrace) do case Exception.normalize(kind, ex, stacktrace) do - %struct{} = ex -> - {to_string(struct), Exception.message(ex)} - - other -> - {to_string(kind), to_string(other)} + %struct{} = ex -> {to_string(struct), Exception.message(ex)} + payload -> {to_string(kind), safe_to_string(payload)} end end + defp safe_to_string(term) do + to_string(term) + rescue + Protocol.UndefinedError -> + inspect(term) + end + defp exception_breadcrumbs(exception) do case exception do {_kind, exception} -> exception_breadcrumbs(exception) diff --git a/live.exs b/live.exs index ce17e41..a5f10bd 100644 --- a/live.exs +++ b/live.exs @@ -1,7 +1,6 @@ Mix.install([ - {:phoenix_playground, - github: "phoenix-playground/phoenix_playground", - ref: "ee6da0fc3b141f78b9f967ce71a4fb015c6764a6"}, + {:phoenix_playground, "~> 0.1.7"}, + {:postgrex, "~> 0.19.3"}, {:error_tracker, path: "."} ]) @@ -13,6 +12,7 @@ end Application.put_env(:error_tracker, :repo, ErrorTrackerDev.Repo) Application.put_env(:error_tracker, :application, :error_tracker_dev) Application.put_env(:error_tracker, :prefix, "private") +Application.put_env(:error_tracker, :otp_app, :error_tracker_dev) Application.put_env(:error_tracker, ErrorTrackerDev.Repo, url: "ecto://postgres:postgres@127.0.0.1/error_tracker_dev" @@ -26,6 +26,29 @@ defmodule Migration0 do def down, do: ErrorTracker.Migration.down(prefix: "private") end +defmodule ErrorTrackerDev.TimeoutGenServer do + use GenServer + + # Client + + def start_link(_) do + GenServer.start_link(__MODULE__, %{}) + end + + # Server (callbacks) + + @impl true + def init(initial_state) do + {:ok, initial_state} + end + + @impl true + def handle_call(:timeout, _from, state) do + :timer.sleep(5000) + {:reply, state, state} + end +end + defmodule DemoLive do use Phoenix.LiveView @@ -47,6 +70,7 @@ defmodule DemoLive do + <.link href="/?crash=mount">Crash on mount <.link patch="/?crash=handle_params">Crash on handle_params @@ -69,6 +93,11 @@ defmodule DemoLive do raise "Crash on handle_event" end + def handle_event("genserver-timeout", _params, socket) do + GenServer.call(TimeoutGenServer, :timeout, 2000) + {:noreply, socket} + end + def handle_params(params, _uri, socket) do if params["crash"] == "handle_params" do raise "Crash on handle_params" @@ -78,7 +107,42 @@ defmodule DemoLive do end end -PhoenixPlayground.start(live: DemoLive, child_specs: [ErrorTrackerDev.Repo]) +defmodule DemoRouter do + use Phoenix.Router + use ErrorTracker.Web, :router + + import Phoenix.LiveView.Router + + pipeline :browser do + plug :put_root_layout, html: {PhoenixPlayground.Layout, :root} + end + + scope "/" do + pipe_through :browser + live "/", DemoLive + error_tracker_dashboard "/errors" + end +end + +defmodule DemoEndpoint do + use Phoenix.Endpoint, otp_app: :phoenix_playground + plug Plug.Logger + socket "/live", Phoenix.LiveView.Socket + plug Plug.Static, from: {:phoenix, "priv/static"}, at: "/assets/phoenix" + plug Plug.Static, from: {:phoenix_live_view, "priv/static"}, at: "/assets/phoenix_live_view" + socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket + plug Phoenix.LiveReloader + plug Phoenix.CodeReloader, reloader: &PhoenixPlayground.CodeReloader.reload/2 + plug DemoRouter +end + +PhoenixPlayground.start( + endpoint: DemoEndpoint, + child_specs: [ + {ErrorTrackerDev.Repo, []}, + {ErrorTrackerDev.TimeoutGenServer, [name: TimeoutGenServer]} + ] +) # Create the database if it does not exist and run migrations if needed _ = Ecto.Adapters.Postgres.storage_up(ErrorTrackerDev.Repo.config())