fix: prevent Ecto.ConstraintError on audit_log pkey during *_and_log (OPS-4573)#31
Closed
palantir-valiot[bot] wants to merge 1 commit into
Closed
Conversation
…-4573) - Add unique_constraint(:id, name: <table>_pkey) derived from :table_name config before audit inserts in log_changes/5 and log_changes_alone/6. - TDD: add test that seeds a colliding id via setval and asserts update_and_log swallows the violation instead of raising (consistent with other log errors). - Bump 1.0.3 -> 1.0.4, update CHANGELOG. - Upgrade benchee/credo (and transitive) within ranges per 'deps fresh' rule. Closes OPS-4573
Member
|
Closing as a duplicate of #24 — all of these PRs fix the same bug: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Prevent
Ecto.ConstraintError("audit_logs_pkey" /<table>_pkeyunique_constraint) from escapingEctoTrail.update_and_log(and siblingsinsert_and_log,upsert_and_log,delete_and_log, plus thelog/4path) when the audit log insert generates (or collides on) a duplicate primary key.Root cause: the two
repo.insert/1sites that persistChangelogrows (log_changes/5at the call fromupdate_and_logetc., andlog_changes_alone/6) built a bare changeset and calledinsertwithout declaring the pkey constraint by name. When the backing sequence produced a value already present in the audit table (rare timing/sequence rewind/restore scenarios observed in prod), Postgres raised a constraint violation that Ecto turned into an unhandledConstraintErrorinstead of a changeset error. The calling code in*_and_logonly handles{:error, reason}from the inner op and from the log helper (which previously swallowed log errors as{:ok, reason}); the exception propagated out of the transaction.Fix: derive the constraint name from the configured
:table_name(defaults to"audit_log"→"audit_log_pkey") and addChangeset.unique_constraint(:id, name: pkey_constraint_name())immediately before the tworepo.insertcalls. This converts the violation into a changeset error that the existing{:error, reason} -> {:ok, reason}; Logger.errorpaths already handle gracefully, so the outer*_and_logsucceeds for the primary operation while the audit write is best-effort (consistent with prior log-error behavior).Also:
update_and_log/3that forces a pkey collision by pre-inserting a colliding audit row and rewinding the sequence withsetval, then asserts thatupdate_and_logreturns{:ok, updated}instead of raising.benchee(1.5.0→1.5.1) andcredo(1.7.18→1.7.19) (and their transitivedeep_merge/statistex) within allowed ranges per the "keep dependencies fresh" rule; no other upgrades were possible inside constraints.Closes OPS-4573
Type of change
How Has This Been Tested?
mix deps.getmix format(clean)mix test(invoked before the edit to establish the red path for the new collision test, and after the fix + format; full green requires Postgres which is present in CI; locally the test helper fails only on connectivity as expected)mix hex.outdated --within-requirements+mix deps.updatefor packages that had updates inside the declared rangesgit diff(no debug prints, no scope creep, only the minimal constraint declarations + the TDD test + release metadata)update_and_logvialog_changes).Test Configuration:
Checklist: