Skip to content

Commit c33ff7a

Browse files
committed
fix: address critical issues in Qwen OAuth implementation
- Add mutex/promise-based deduplication to prevent race conditions in token refresh - Add error handling for credential file write operations - Ensure only one token refresh happens at a time for concurrent requests - Continue with refreshed token in memory if file write fails Addresses review feedback from PR #7380
1 parent b07d8ad commit c33ff7a

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/api/providers/qwen-code.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export class QwenCodeHandler extends BaseProvider implements SingleCompletionHan
5252
protected options: QwenCodeHandlerOptions
5353
private credentials: QwenOAuthCredentials | null = null
5454
private client: OpenAI | undefined
55+
private refreshPromise: Promise<QwenOAuthCredentials> | null = null
5556

5657
constructor(options: QwenCodeHandlerOptions) {
5758
super()
@@ -84,6 +85,24 @@ export class QwenCodeHandler extends BaseProvider implements SingleCompletionHan
8485
}
8586

8687
private async refreshAccessToken(credentials: QwenOAuthCredentials): Promise<QwenOAuthCredentials> {
88+
// If a refresh is already in progress, return the existing promise
89+
if (this.refreshPromise) {
90+
return this.refreshPromise
91+
}
92+
93+
// Create a new refresh promise
94+
this.refreshPromise = this.doRefreshAccessToken(credentials)
95+
96+
try {
97+
const result = await this.refreshPromise
98+
return result
99+
} finally {
100+
// Clear the promise after completion (success or failure)
101+
this.refreshPromise = null
102+
}
103+
}
104+
105+
private async doRefreshAccessToken(credentials: QwenOAuthCredentials): Promise<QwenOAuthCredentials> {
87106
if (!credentials.refresh_token) {
88107
throw new Error("No refresh token available in credentials.")
89108
}
@@ -123,7 +142,12 @@ export class QwenCodeHandler extends BaseProvider implements SingleCompletionHan
123142
}
124143

125144
const filePath = getQwenCachedCredentialPath(this.options.qwenCodeOauthPath)
126-
await fs.writeFile(filePath, JSON.stringify(newCredentials, null, 2))
145+
try {
146+
await fs.writeFile(filePath, JSON.stringify(newCredentials, null, 2))
147+
} catch (error) {
148+
console.error("Failed to save refreshed credentials:", error)
149+
// Continue with the refreshed token in memory even if file write fails
150+
}
127151

128152
return newCredentials
129153
}

0 commit comments

Comments
 (0)