fix(qqbot): guard token expiry logging · openclaw/openclaw@6b14df7
steipete
·
2026-05-30
·
via Recent Commits to openclaw:main
File tree
extensions/qqbot/src/engine/api
| Original file line number | Diff line number | Diff line change |
|---|
@@ -86,4 +86,25 @@ describe("QQBot token manager", () => {
|
86 | 86 | expiresAt: Date.now(), |
87 | 87 | }); |
88 | 88 | }); |
| 89 | + |
| 90 | +it("does not throw while logging fetched tokens when the process clock is outside the Date range", async () => { |
| 91 | +const logger = { debug: vi.fn(), info: vi.fn(), error: vi.fn() }; |
| 92 | +const dateNowSpy = vi.spyOn(Date, "now").mockReturnValue(8_640_000_000_000_001); |
| 93 | +mockGuardedTokenResponse('{"access_token":"token-1","expires_in":7200}', { |
| 94 | +status: 200, |
| 95 | +headers: { "content-type": "application/json" }, |
| 96 | +}); |
| 97 | + |
| 98 | +const manager = new TokenManager({ logger }); |
| 99 | +try { |
| 100 | +await expect(manager.getAccessToken("app-id", "secret")).resolves.toBe("token-1"); |
| 101 | +} finally { |
| 102 | +dateNowSpy.mockRestore(); |
| 103 | +} |
| 104 | + |
| 105 | +expect(manager.getStatus("app-id").expiresAt).toBe(7_200_000); |
| 106 | +expect(logger.debug).toHaveBeenCalledWith( |
| 107 | +"[qqbot:token:app-id] Cached, expires at: 1970-01-01T02:00:00.000Z", |
| 108 | +); |
| 109 | +}); |
89 | 110 | }); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -6,7 +6,12 @@
|
6 | 6 | * globals, fully supporting multi-account concurrent operation. |
7 | 7 | */ |
8 | 8 | |
9 | | -import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime"; |
| 9 | +import { |
| 10 | +parseStrictPositiveInteger, |
| 11 | +resolveDateTimestampMs, |
| 12 | +resolveExpiresAtMsFromDurationSeconds, |
| 13 | +resolveTimestampMsToIsoString, |
| 14 | +} from "openclaw/plugin-sdk/number-runtime"; |
10 | 15 | import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime"; |
11 | 16 | import type { EngineLogger } from "../types.js"; |
12 | 17 | import { formatErrorMessage } from "../utils/format.js"; |
@@ -273,10 +278,14 @@ export class TokenManager {
|
273 | 278 | throw new Error(`Failed to get access_token: ${JSON.stringify(data)}`); |
274 | 279 | } |
275 | 280 | |
276 | | -const expiresAt = Date.now() + resolveTokenExpiresInSeconds(data.expires_in) * 1000; |
| 281 | +const nowMs = resolveDateTimestampMs(Date.now()); |
| 282 | +const expiresAt = |
| 283 | +resolveExpiresAtMsFromDurationSeconds(resolveTokenExpiresInSeconds(data.expires_in), { |
| 284 | + nowMs, |
| 285 | +}) ?? nowMs; |
277 | 286 | this.cache.set(appId, { token: data.access_token, expiresAt, appId }); |
278 | 287 | this.logger?.debug?.( |
279 | | -`[qqbot:token:${appId}] Cached, expires at: ${new Date(expiresAt).toISOString()}`, |
| 288 | +`[qqbot:token:${appId}] Cached, expires at: ${resolveTimestampMsToIsoString(expiresAt)}`, |
280 | 289 | ); |
281 | 290 | |
282 | 291 | return data.access_token; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。