towerops/test/towerops/error_tracker_ignorer_test.exs
Graham McIntire a99c327446 fix: apply Oban Pro 1.7 follow-up cleanup + filter transient DB noise
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.
2026-05-01 16:04:05 -05:00

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