Commit 8ed4f52
committed
fix(oauth): 🐛 prevent deadlock and token desync for rotating refresh tokens
This commit fixes critical issues in OAuth providers (Google, iFlow, Qwen) that use rotating refresh tokens, where each token refresh invalidates the previous token.
**Problems Fixed:**
1. **Deadlock Prevention**: Removed inline re-authentication from `refresh_token()` method that was called while holding a lock. When refresh failed with HTTP 400/401/403, the method would call `initialize_token()` directly, which would try to acquire the same lock, causing a deadlock. Now, invalid token errors are caught and queued for background re-authentication via `asyncio.create_task()`.
2. **Token Desync**: Changed `_save_credentials()` to write to disk FIRST, then update cache. Previously, cache was updated first with `buffer_on_failure=True`, which could leave stale tokens on disk if the write failed. For rotating tokens, this caused the old refresh_token on disk to become invalid after a successful API call, requiring re-auth on restart.
3. **Stale Cache Usage**: Modified `refresh_token()` to always read fresh credentials from disk before refreshing, preventing use of stale cached tokens that may have been invalidated by another process.
4. **New Error Type**: Introduced `CredentialNeedsReauthError` exception to signal rotatable authentication failures. This allows the client to rotate to the next credential without logging scary tracebacks, while background re-auth fixes the broken credential.
**Changes:**
- Add `CredentialNeedsReauthError` exception class and classification in error_handler.py
- Catch and wrap `CredentialNeedsReauthError` in client.py retry loop
- Replace inline re-auth with background task queuing in all OAuth providers
- Change `_save_credentials()` to disk-first writes with no buffering for rotating tokens
- Add `force_interactive` parameter to `initialize_token()` for explicit re-auth requests
- Always reload credentials from disk before refresh to prevent stale token usage
- Return boolean from `_save_credentials()` and raise IOError on critical failures
- Update re-auth queue processing to call `initialize_token(force_interactive=True)`1 parent a68d8d0 commit 8ed4f52
File tree
5 files changed
+408
-167
lines changed- src/rotator_library
- providers
5 files changed
+408
-167
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
| |||
755 | 756 | | |
756 | 757 | | |
757 | 758 | | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
758 | 765 | | |
759 | 766 | | |
760 | 767 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
117 | 117 | | |
118 | 118 | | |
119 | 119 | | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
120 | 145 | | |
121 | 146 | | |
122 | 147 | | |
| |||
698 | 723 | | |
699 | 724 | | |
700 | 725 | | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
701 | 734 | | |
702 | 735 | | |
703 | 736 | | |
| |||
789 | 822 | | |
790 | 823 | | |
791 | 824 | | |
| 825 | + | |
792 | 826 | | |
793 | 827 | | |
794 | 828 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
366 | 367 | | |
367 | 368 | | |
368 | 369 | | |
369 | | - | |
370 | 370 | | |
371 | 371 | | |
372 | 372 | | |
| |||
390 | 390 | | |
391 | 391 | | |
392 | 392 | | |
393 | | - | |
394 | | - | |
395 | | - | |
396 | | - | |
397 | | - | |
398 | | - | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
399 | 428 | | |
400 | | - | |
401 | | - | |
402 | 429 | | |
403 | 430 | | |
404 | 431 | | |
| |||
438 | 465 | | |
439 | 466 | | |
440 | 467 | | |
441 | | - | |
442 | | - | |
443 | | - | |
444 | | - | |
445 | | - | |
446 | | - | |
447 | | - | |
448 | | - | |
449 | | - | |
450 | | - | |
451 | | - | |
452 | | - | |
453 | | - | |
454 | | - | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | 468 | | |
459 | 469 | | |
460 | 470 | | |
| |||
832 | 842 | | |
833 | 843 | | |
834 | 844 | | |
835 | | - | |
| 845 | + | |
836 | 846 | | |
837 | 847 | | |
838 | 848 | | |
| |||
1058 | 1068 | | |
1059 | 1069 | | |
1060 | 1070 | | |
1061 | | - | |
| 1071 | + | |
| 1072 | + | |
| 1073 | + | |
1062 | 1074 | | |
1063 | 1075 | | |
1064 | 1076 | | |
1065 | 1077 | | |
1066 | 1078 | | |
1067 | 1079 | | |
1068 | 1080 | | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
1069 | 1087 | | |
1070 | 1088 | | |
1071 | 1089 | | |
| |||
1085 | 1103 | | |
1086 | 1104 | | |
1087 | 1105 | | |
1088 | | - | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
1089 | 1111 | | |
1090 | 1112 | | |
1091 | 1113 | | |
| |||
0 commit comments