fix: stop replaying non-idempotent requests and expose the rotation grace
A retried POST /v1/auth/rotate loses the replacement token because the presented token is already in grace, and a retried webhook registration creates duplicates. Only idempotent methods now retry a 429 or 5xx. Add previous_token_grace_until to RotateApiTokenResponse. Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq
This commit is contained in:
1 parent
89bdd6e3b8
commit
a63c360539
2 files changed
+9
-1
No files matched your search
+8
-1
@@ -344,7 +344,7 @@ export class ElydoraClient {
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
|
||||
if (attempt < this.maxRetries && (res.status === 429 || res.status >= 500)) {
|
||||
if (attempt < this.maxRetries && isIdempotent(method) && (res.status === 429 || res.status >= 500)) {
|
||||
const retryAfter = res.headers.get('Retry-After');
|
||||
const delayMs = retryAfter
|
||||
? parseInt(retryAfter, 10) * 1000
|
||||
@@ -372,6 +372,13 @@ export class ElydoraClient {
|
||||
}
|
||||
}
|
||||
|
||||
const IDEMPOTENT_METHODS = new Set(['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE']);
|
||||
|
||||
/** A lost response to a non-idempotent request must not be replayed. */
|
||||
function isIdempotent(method: string): boolean {
|
||||
return IDEMPOTENT_METHODS.has(method.toUpperCase());
|
||||
}
|
||||
|
||||
async function handleResponse<T>(res: Response): Promise<T> {
|
||||
if (res.ok) {
|
||||
if (res.status === 204) {
|
||||
|
||||
@@ -384,6 +384,7 @@ export interface RotateApiTokenResponse {
|
||||
readonly token: string;
|
||||
readonly expires_at: number | null;
|
||||
readonly token_id: string;
|
||||
readonly previous_token_grace_until: number;
|
||||
}
|
||||
|
||||
export interface HealthResponse {
|
||||
|
||||
Reference in new issue
Block a user