whisper-money/app
Víctor Falcón 8bbff05b26
fix(banking): only log sync failures once the connection gives up (#603)
## Why

Production log dashboards were flooded with paired `Banking sync failed`
+ `EnableBanking API error` warnings for a handful of users, recurring
on every 6-hour `banking:sync` cycle for days. Investigation (prod
`BankingSyncLog` + connection state) showed the affected connections are
**healthy and syncing daily** (`last_synced_at` = today,
`consecutive_sync_failures = 0`): the first attempt hits a transient
`ASPSP_ERROR` / `429`, and the job's retry recovers it.

So the warnings are **noise, not breakage** — but
`SyncBankingConnectionJob` logged `Banking sync failed` inside the catch
block on *every* attempt, including non-final ones that later succeed.
That's one warning per cycle for connections that sync fine, which reads
as a failure and causes alert fatigue.

## What

Gate the `Log::log(...)` call so it only fires when the connection
actually gives up:

- the **final attempt** (`attempts() >= tries`), or
- a **permanent auth error** (`isAuthError`).

Transient errors recovered by the retry are no longer logged.
Per-attempt traceability is unchanged: `BankingSyncLog` still records
every attempt (Success / Failed) in the database.

## Tests

`tests/Feature/OpenBanking/SyncRetryAndLoggingTest.php`:
- non-final attempt → `Log::log` is **not** called
- final attempt → `Log::log('error', 'Banking sync failed', ...)` **is**
called once

Full file: 24/24 passing.
2026-06-27 16:04:36 +00:00
..
Actions feat(subscriptions): trial/pricing A/B/C experiment (#600) 2026-06-27 18:00:15 +02:00
Ai/Agents feat(ai): auto-categorize transactions with AI (behind flag) (#535) 2026-06-15 16:35:20 +02:00
Console/Commands feat(subscriptions): trial/pricing A/B/C experiment (#600) 2026-06-27 18:00:15 +02:00
Contracts feat(connections): manage which accounts a bank connection syncs (#558) 2026-06-18 16:22:49 +02:00
Enums feat(integration-requests): add done status and fix review command crash on orphaned author (#601) 2026-06-27 14:42:09 +00:00
Events Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
Exceptions/Banking fix(banking): skip inaccessible EnableBanking accounts instead of failing the connection (#559) 2026-06-19 08:59:05 +02:00
Features feat(subscriptions): trial/pricing A/B/C experiment (#600) 2026-06-27 18:00:15 +02:00
Http fix(open-banking): stop storing the XXX no-currency placeholder on accounts (#602) 2026-06-27 16:01:21 +00:00
Jobs fix(banking): only log sync failures once the connection gives up (#603) 2026-06-27 16:04:36 +00:00
Listeners fix(discord): skip zero-amount payment stats messages (#540) 2026-06-15 19:21:47 +02:00
Mail feat(email): follow up after post-onboarding AI consent (#596) 2026-06-26 17:56:06 +00:00
Models feat(email): follow up after post-onboarding AI consent (#596) 2026-06-26 17:56:06 +00:00
Notifications fix: verify email via signed link without requiring login (#490) 2026-06-05 10:01:32 +02:00
Policies refactor(policies): extract HandlesUserOwnership trait (#478) 2026-06-03 17:43:30 +02:00
Providers feat(demo): gate demo account access behind a config flag (#580) 2026-06-22 11:01:27 +00:00
Rules feat: parent/child category tree (#474) 2026-06-03 19:30:12 +02:00
Services fix(open-banking): stop storing the XXX no-currency placeholder on accounts (#602) 2026-06-27 16:01:21 +00:00