Skip to content

Commit e1051fc

Browse files
authored
Merge pull request #1198 from code-corps/1192-save-changeset-errors
Save changeset errors and data for GitHub webhooks
2 parents f82f9cd + 7b77518 commit e1051fc

File tree

19 files changed

+151
-28
lines changed

19 files changed

+151
-28
lines changed

config/config.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ config :sentry,
8282
included_environments: ~w(prod staging)a,
8383
use_error_logger: true
8484

85+
config :code_corps, :sentry, CodeCorps.Sentry.Async
86+
8587
config :code_corps, :processor, CodeCorps.Processor.Async
8688

8789
# Import environment specific config. This must remain at the bottom

config/test.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ config :code_corps,
5757
config :sentry,
5858
environment_name: Mix.env || :test
5959

60+
config :code_corps, :sentry, CodeCorps.Sentry.Sync
61+
6062
config :code_corps, :processor, CodeCorps.Processor.Sync
6163

6264
config :code_corps, CodeCorps.Mailer,

lib/code_corps/github/event.ex

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ defmodule CodeCorps.GitHub.Event do
77
alias CodeCorps.{GithubEvent, Repo}
88
alias Ecto.Changeset
99

10+
defmodule GitHubEventError do
11+
defexception [:reason]
12+
13+
def exception(reason),
14+
do: %__MODULE__{reason: reason}
15+
16+
def message(%__MODULE__{reason: reason}),
17+
do: reason
18+
end
19+
1020
@type error :: atom | Changeset.t
1121

1222
@doc ~S"""
@@ -33,11 +43,24 @@ defmodule CodeCorps.GitHub.Event do
3343
|> Changeset.change(%{status: "processed"})
3444
|> Repo.update()
3545
end
36-
def stop_processing({:error, reason}, %GithubEvent{} = event) do
37-
changes = %{status: "errored", failure_reason: reason |> Atom.to_string}
46+
def stop_processing({:error, reason, error}, %GithubEvent{} = event) do
47+
%GitHubEventError{reason: error}
48+
|> CodeCorps.Sentry.capture_exception([stacktrace: System.stacktrace()])
49+
50+
changes = %{
51+
status: "errored",
52+
data: error |> format_data_if_exists(),
53+
error: error |> Kernel.inspect(pretty: true),
54+
failure_reason: reason |> Atom.to_string()
55+
}
3856

3957
event
4058
|> Changeset.change(changes)
4159
|> Repo.update()
4260
end
61+
62+
defp format_data_if_exists(%Ecto.Changeset{data: data}) do
63+
data |> Kernel.inspect(pretty: true)
64+
end
65+
defp format_data_if_exists(_error), do: nil
4366
end

lib/code_corps/github/sync/sync.ex

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ defmodule CodeCorps.GitHub.Sync do
2020
@type outcome :: {:ok, list(Comment.t)}
2121
| {:ok, GithubPullRequest.t}
2222
| {:ok, list(CodeCorps.Task.t)}
23-
| {:error, :repo_not_found}
23+
| {:error, :repo_not_found, %{}}
2424
| {:error, :fetching_issue}
2525
| {:error, :fetching_pull_request}
2626
| {:error, :multiple_issue_users_match}
@@ -232,18 +232,17 @@ defmodule CodeCorps.GitHub.Sync do
232232
defp marshall_result({:ok, %{github_pull_request: _, github_issue: _}} = result), do: result
233233
defp marshall_result({:ok, %{github_pull_request: pull_request}}), do: {:ok, pull_request}
234234
defp marshall_result({:ok, %{task: task}}), do: {:ok, task}
235-
defp marshall_result({:error, :repo, :unmatched_project, _steps}), do: {:ok, []}
236-
defp marshall_result({:error, :repo, :unmatched_repository, _steps}), do: {:error, :repo_not_found}
237-
defp marshall_result({:error, :fetch_issue, _, _steps}), do: {:error, :fetching_issue}
238-
defp marshall_result({:error, :fetch_pull_request, _, _steps}), do: {:error, :fetching_pull_request}
239-
defp marshall_result({:error, :github_pull_request, %Ecto.Changeset{}, _steps}), do: {:error, :validating_github_pull_request}
240-
defp marshall_result({:error, :github_issue, %Ecto.Changeset{}, _steps}), do: {:error, :validating_github_issue}
241-
defp marshall_result({:error, :github_comment, %Ecto.Changeset{}, _steps}), do: {:error, :validating_github_comment}
242-
defp marshall_result({:error, :comment_user, %Ecto.Changeset{}, _steps}), do: {:error, :validating_user}
243-
defp marshall_result({:error, :comment_user, :multiple_users, _steps}), do: {:error, :multiple_comment_users_match}
244-
defp marshall_result({:error, :issue_user, %Ecto.Changeset{}, _steps}), do: {:error, :validating_user}
245-
defp marshall_result({:error, :issue_user, :multiple_users, _steps}), do: {:error, :multiple_issue_users_match}
246-
defp marshall_result({:error, :comment, {_comments, _errors}, _steps}), do: {:error, :validating_comment}
247-
defp marshall_result({:error, :task, %Ecto.Changeset{}, _steps}), do: {:error, :validating_task}
248-
defp marshall_result({:error, _errored_step, _error_response, _steps}), do: {:error, :unexpected_transaction_outcome}
235+
defp marshall_result({:error, :repo, :unmatched_repository, _steps}), do: {:error, :repo_not_found, %{}}
236+
defp marshall_result({:error, :fetch_issue, _, _steps}), do: {:error, :fetching_issue, %{}}
237+
defp marshall_result({:error, :fetch_pull_request, _, _steps}), do: {:error, :fetching_pull_request, %{}}
238+
defp marshall_result({:error, :github_pull_request, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_github_pull_request, changeset}
239+
defp marshall_result({:error, :github_issue, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_github_issue, changeset}
240+
defp marshall_result({:error, :github_comment, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_github_comment, changeset}
241+
defp marshall_result({:error, :comment_user, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_user, changeset}
242+
defp marshall_result({:error, :comment_user, :multiple_users, _steps}), do: {:error, :multiple_comment_users_match, %{}}
243+
defp marshall_result({:error, :issue_user, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_user, changeset}
244+
defp marshall_result({:error, :issue_user, :multiple_users, _steps}), do: {:error, :multiple_issue_users_match, %{}}
245+
defp marshall_result({:error, :comment, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_comment, changeset}
246+
defp marshall_result({:error, :task, %Ecto.Changeset{} = changeset, _steps}), do: {:error, :validating_task, changeset}
247+
defp marshall_result({:error, _errored_step, error_response, _steps}), do: {:error, :unexpected_transaction_outcome, error_response}
249248
end

lib/code_corps/model/github_event.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ defmodule CodeCorps.GithubEvent do
66

77
schema "github_events" do
88
field :action, :string
9+
field :data, :string
910
field :failure_reason, :string
1011
field :github_delivery_id, :string
1112
field :payload, :map
13+
field :error, :string
1214
field :status, :string
1315
field :type, :string
1416

@@ -20,7 +22,7 @@ defmodule CodeCorps.GithubEvent do
2022
"""
2123
def changeset(struct, params \\ %{}) do
2224
struct
23-
|> cast(params, [:action, :github_delivery_id, :payload, :status, :type])
25+
|> cast(params, [:action, :data, :github_delivery_id, :payload, :error, :status, :type])
2426
|> validate_required([:action, :github_delivery_id, :payload, :status, :type])
2527
end
2628
end

lib/code_corps/sentry/async.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
defmodule CodeCorps.Sentry.Async do
2+
def capture_exception(exception, opts \\ []) do
3+
exception
4+
|> Sentry.capture_exception(opts)
5+
end
6+
end

lib/code_corps/sentry/sentry.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defmodule CodeCorps.Sentry do
2+
@sentry Application.get_env(:code_corps, :sentry)
3+
4+
def capture_exception(exception, opts \\ []) do
5+
@sentry.capture_exception(exception, opts)
6+
end
7+
end

lib/code_corps/sentry/sync.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
defmodule CodeCorps.Sentry.Sync do
2+
def capture_exception(exception, opts \\ []) do
3+
exception
4+
|> Sentry.capture_exception(opts |> Keyword.put(:result, :sync))
5+
end
6+
end

lib/code_corps_web/views/github_event_view.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ defmodule CodeCorpsWeb.GithubEventView do
44
use JaSerializer.PhoenixView
55

66
attributes [
7-
:action, :event_type, :failure_reason, :github_delivery_id, :inserted_at,
8-
:payload, :status, :updated_at
7+
:action, :data, :event_type, :error, :failure_reason, :github_delivery_id,
8+
:inserted_at, :payload, :status, :updated_at
99
]
1010

1111
def event_type(github_event, _conn) do
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
defmodule CodeCorps.Repo.Migrations.AddSerializedErrorToGithubEvents do
2+
use Ecto.Migration
3+
4+
def change do
5+
alter table(:github_events) do
6+
add :data, :text
7+
add :error, :text
8+
end
9+
end
10+
end

0 commit comments

Comments
 (0)