-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathevent.ex
More file actions
70 lines (60 loc) · 2.16 KB
/
event.ex
File metadata and controls
70 lines (60 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
defmodule CodeCorps.GitHub.Event do
@moduledoc ~S"""
In charge of marking `GithubEvent` records as "processing", "processed" or
"errored", based on the outcome of processing a webhook event payload.
"""
alias CodeCorps.{GithubEvent, Repo}
alias Ecto.Changeset
defmodule GitHubEventError do
defexception [:reason]
def exception(reason),
do: %__MODULE__{reason: reason}
def message(%__MODULE__{reason: reason}),
do: reason
end
@type error :: atom | Changeset.t
@type result :: {:ok, any} | {:error, atom} | {:error, atom, any}
@doc ~S"""
Sets record status to "processing", marking it as being processed at this
moment. Our webhook handling should skip processing payloads for events which
are already being processed.
"""
@spec start_processing(GithubEvent.t) :: {:ok, GithubEvent.t}
def start_processing(%GithubEvent{} = event) do
event
|> Changeset.change(%{status: "processing"})
|> Repo.update()
end
@doc ~S"""
Sets record status to "processed" or "errored" based on the first element of
first argument, which is the result tuple. The first element of the result
tuple should always be either `:ok`, or `:error`. Any number of elements in
the tuple is suported.
"""
@spec stop_processing(result, GithubEvent.t) :: {:ok, GithubEvent.t}
def stop_processing({:ok, _data}, %GithubEvent{} = event) do
event
|> Changeset.change(%{status: "processed"})
|> Repo.update()
end
def stop_processing({:error, reason}, %GithubEvent{} = event) do
stop_processing({:error, reason, %{}}, event)
end
def stop_processing({:error, reason, error}, %GithubEvent{} = event) do
%GitHubEventError{reason: error}
|> CodeCorps.Sentry.capture_exception([stacktrace: System.stacktrace()])
changes = %{
status: "errored",
data: error |> format_data_if_exists(),
error: error |> Kernel.inspect(pretty: true),
failure_reason: reason |> Atom.to_string()
}
event
|> Changeset.change(changes)
|> Repo.update()
end
defp format_data_if_exists(%Ecto.Changeset{data: data}) do
data |> Kernel.inspect(pretty: true)
end
defp format_data_if_exists(_error), do: nil
end