The 1.7 upgrade migration added the new oban_workflows tracking but left behind legacy state from earlier versions that the upgrade guide strongly recommends removing (https://oban.pro/docs/pro/v1-7.html): - The uniq_key / partition_key GENERATED ALWAYS columns. The Smart engine no longer reads them; uniqueness and partition lookups now use expression indexes on meta. Keeping the columns imposes write overhead on every oban_jobs insert/update and was contributing to intermittent transaction-rollback errors. - The oban_jobs_*_old workflow/chain indexes. v1.7 renamed the originals and built expression-based replacements; the _old indexes are dead weight that still slow down writes. Also extend ErrorTrackerIgnorer to drop transient DBConnection.ConnectionError noise ("connection is closed", "transaction rolling back"). These come from the Repo's intentional queue-target / disconnect-on-error cycling that recovers from stale SSL connections — Ecto retries automatically, so logging adds noise without value.
60 lines
1.8 KiB
Elixir
60 lines
1.8 KiB
Elixir
defmodule Towerops.ErrorTrackerIgnorerTest do
|
|
use ExUnit.Case, async: true
|
|
|
|
alias Towerops.ErrorTrackerIgnorer
|
|
|
|
defp build_error(reason, kind \\ "ErlangError") do
|
|
%ErrorTracker.Error{
|
|
kind: kind,
|
|
reason: reason,
|
|
source_line: "-",
|
|
source_function: "-",
|
|
status: :unresolved,
|
|
fingerprint: "abc",
|
|
last_occurrence_at: DateTime.utc_now(),
|
|
muted: false
|
|
}
|
|
end
|
|
|
|
describe "ignore?/2" do
|
|
test "ignores port_died errors" do
|
|
error = build_error("Erlang error: {:port_died, :normal}")
|
|
assert ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
|
|
test "ignores write_failed errors" do
|
|
error = build_error("{:write_failed, :standard_io, :enoent}")
|
|
assert ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
|
|
test "ignores epipe errors" do
|
|
error = build_error("{:error, {:write_failed, %{type: :standard_io}, {:badarg, :epipe}}}")
|
|
assert ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
|
|
test "ignores broken pipe errors" do
|
|
error = build_error("broken pipe (epipe)")
|
|
assert ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
|
|
test "ignores transient DBConnection.ConnectionError closures" do
|
|
error =
|
|
build_error(
|
|
"connection is closed because of an error, disconnect or timeout",
|
|
"Elixir.DBConnection.ConnectionError"
|
|
)
|
|
|
|
assert ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
|
|
test "does not ignore regular errors" do
|
|
error = build_error("something went wrong")
|
|
refute ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
|
|
test "does not ignore other DBConnection errors" do
|
|
error = build_error("ownership timeout", "Elixir.DBConnection.ConnectionError")
|
|
refute ErrorTrackerIgnorer.ignore?(error, %{})
|
|
end
|
|
end
|
|
end
|