Fix(exchange_rate): Handle RecordInvalid in find_or_fetch_rate race condition (#2734)

Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
This commit is contained in:
sentry[bot]
2026-07-30 03:05:14 +02:00
committed by GitHub
parent cedf28a5a9
commit 32eef8e2ea

View File

@@ -41,10 +41,12 @@ module ExchangeRate::Provided
) do |exchange_rate|
exchange_rate.rate = rate.rate
end if cache
rescue ActiveRecord::RecordNotUnique
# Race condition: another process inserted between our SELECT and INSERT
# Retry by finding the existing record
ExchangeRate.find_by!(
rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
# Race condition: another process inserted between our SELECT and INSERT.
# RecordNotUnique = DB unique constraint; RecordInvalid = model uniqueness
# validation fired before the DB got a chance to reject it. Both are safe
# to handle by reading back the record that the other process just saved.
return ExchangeRate.find_by!(
from_currency: rate.from,
to_currency: rate.to,
date: rate.date