Files
OmniRoute/tests/unit
diegosouzapw cb1c5471dd fix(oauth): resilient refresh error classification + healthcheck circuit breaker
Root cause of the production token-invalidation storm (claude/aa5dd5cf
refreshed 1352x, kimi-coding 270x): when a refresh endpoint returned
invalid_grant in a non-canonical body shape (a JSON string, a double-encoded
string, a nested {error:{code}}, or raw text wrapped by a proxy/MITM),
refreshClaudeOAuthToken's errorBody.error === "invalid_grant" check failed and
returned null instead of the unrecoverable sentinel. The HealthCheck then kept
the connection active and re-tried every 60s forever (the loop + log flood +
upstream hammering that contributed to the 429s).

- extractOAuthErrorCode(): shape-agnostic OAuth error extractor (object, nested,
  bare string, double-encoded JSON string, raw text) restricted to a known
  unrecoverable set so transient errors (server_error, 502 HTML) never become
  false positives.
- refreshClaudeOAuthToken + refreshAccessToken/Cline/Qoder/GitHub now classify
  invalid_grant/invalid_request via the helper -> always emit the unrecoverable
  sentinel so the HealthCheck deactivates cleanly instead of looping.
- HealthCheck refresh circuit breaker: track consecutive refresh failures in
  providerSpecificData.refreshCircuit and back off exponentially (5->10->20...
  ->240min cap) instead of retrying every 60s; cleared on a successful refresh.
  Stops the loop for null/network failures (e.g. dead proxy / Kimi fetch failed).

TDD: 26 new tests (19 resilience + 7 circuit breaker); 113 oauth/refresh/
healthcheck tests green. typecheck:core=0, lint clean.
2026-06-11 20:53:55 -03:00
..
2026-05-23 01:46:59 -03:00
2026-06-09 22:57:12 -03:00
2026-06-09 22:57:12 -03:00
2026-05-26 23:51:47 -03:00
2026-06-09 22:57:12 -03:00
2026-05-21 01:29:12 -03:00
2026-06-09 22:57:12 -03:00
2026-06-11 04:01:24 -03:00
2026-06-09 22:57:12 -03:00
2026-05-29 12:44:29 -03:00
2026-06-10 13:49:08 -03:00
2026-05-23 01:46:59 -03:00
2026-05-26 23:51:47 -03:00
2026-06-10 13:49:08 -03:00
2026-04-19 19:50:30 -03:00
2026-05-29 12:44:29 -03:00
2026-06-11 04:01:24 -03:00
2026-06-06 19:13:11 -03:00
2026-05-26 23:51:47 -03:00
2026-06-10 13:49:08 -03:00
2026-05-26 23:51:47 -03:00
2026-05-29 12:44:29 -03:00
2026-05-26 23:51:47 -03:00
2026-05-26 23:51:47 -03:00
2026-05-29 12:44:29 -03:00
2026-05-21 01:29:12 -03:00
2026-05-24 18:05:58 -03:00
2026-05-26 23:51:47 -03:00
2026-06-10 13:49:08 -03:00
2026-06-09 22:57:12 -03:00
2026-06-09 22:57:12 -03:00
2026-05-26 23:51:47 -03:00
2026-05-29 12:44:29 -03:00
2026-05-29 12:44:29 -03:00
2026-05-26 23:51:47 -03:00
2026-05-24 18:05:58 -03:00
2026-05-26 23:51:47 -03:00
2026-05-29 12:44:29 -03:00
2026-05-26 23:51:47 -03:00
2026-05-10 00:55:06 -03:00
2026-05-29 19:54:00 -03:00
2026-05-26 23:51:47 -03:00
2026-05-29 12:44:29 -03:00
2026-05-29 12:44:29 -03:00
2026-05-21 01:29:12 -03:00
2026-04-30 01:27:03 -03:00
2026-04-30 01:27:03 -03:00
2026-05-26 23:51:47 -03:00
2026-05-10 00:55:06 -03:00
2026-05-26 23:51:47 -03:00
2026-04-30 14:08:50 -03:00
2026-06-11 04:01:24 -03:00
2026-05-29 12:44:29 -03:00
2026-05-26 23:51:47 -03:00
2026-05-26 23:51:47 -03:00
2026-05-26 23:51:47 -03:00
2026-06-10 13:49:08 -03:00
2026-05-23 01:46:59 -03:00
2026-05-26 23:51:47 -03:00
2026-04-30 01:27:03 -03:00
2026-04-30 01:27:03 -03:00
2026-05-26 23:51:47 -03:00
2026-05-23 01:46:59 -03:00
2026-05-23 01:46:59 -03:00
2026-05-23 01:46:59 -03:00
2026-06-09 15:56:24 -03:00
2026-06-10 13:49:08 -03:00
2026-05-29 19:54:00 -03:00
2026-04-28 10:03:39 -03:00
2026-06-07 07:20:02 -03:00
2026-06-07 07:20:02 -03:00
2026-05-24 18:05:58 -03:00
2026-05-24 18:05:58 -03:00
2026-06-07 07:20:02 -03:00
2026-04-28 20:46:25 -03:00
2026-05-29 12:44:29 -03:00
2026-05-29 12:44:29 -03:00
2026-05-23 01:46:59 -03:00
2026-06-04 20:05:38 -03:00
2026-05-26 23:51:47 -03:00
2026-06-06 19:13:11 -03:00
2026-06-09 15:56:24 -03:00
2026-06-09 15:56:24 -03:00
2026-05-26 23:51:47 -03:00
2026-05-26 23:51:47 -03:00
2026-06-04 20:05:38 -03:00
2026-05-29 12:44:29 -03:00
2026-06-07 07:20:02 -03:00
2026-06-11 04:01:24 -03:00
2026-05-24 18:05:58 -03:00
2026-05-26 23:51:47 -03:00