fix(feishu): clear stale streamingStartPromise on card creation failure#43502
Conversation
Greptile SummaryThis PR fixes a session-lock bug in The fix is a single-line addition — Key changes:
Confidence Score: 5/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/feishu/src/reply-dispatcher.test.ts
Line: 628-629
Comment:
**Push override not restored in `finally` block**
The `streamingInstances.push` restore is executed sequentially in the test body after the assertions. If any assertion before line 629 fails (e.g. `expect(streamingInstances).toHaveLength(2)` on line 632), the override is never cleaned up and persists into subsequent tests.
`beforeEach` resets `streamingInstances.length = 0` but does not reset `streamingInstances.push`, so the override would carry over. In practice it is mostly harmless because `shouldFailStart` is `false` by that point (making the override a no-op passthrough to `origPush`), but it is not idiomatic and could mask subtle issues if the test suite is extended.
Consider wrapping the test body with a `try/finally`:
```ts
const origPush = streamingInstances.push;
try {
streamingInstances.push = function (this: any[], ...args: any[]) {
if (shouldFailStart) {
args[0].start = vi
.fn()
.mockRejectedValue(new Error("Create card request failed with HTTP 400"));
shouldFailStart = false;
}
return origPush.apply(this, args);
} as any;
// ... test body ...
} finally {
streamingInstances.push = origPush;
}
```
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: 6cf243a |
66766cf to
6cf243a
Compare
|
Re: Aisle (CWE-400 unbounded retry) The prior behaviour was a permanent session lock - zero retries, ever. Once Re: Greptile (5/5) Cheers for the thorough analysis. The |
e42a39c to
edd02ee
Compare
25e01f5 to
48548de
Compare
48548de to
9eded44
Compare
|
Rebased onto latest main. CHANGELOG entry verified. All code checks, extensions, and protocol pass. The node test shard and Windows shard failures are from the |
9eded44 to
f87a912
Compare
When FeishuStreamingSession.start() throws (HTTP 400), the catch block sets streaming = null but leaves streamingStartPromise dangling. The guard in startStreaming() checks streamingStartPromise first, so all future deliver() calls silently skip streaming - the session locks permanently. Clear streamingStartPromise in the catch block so subsequent messages can retry streaming instead of dropping all future replies. Fixes openclaw#43322
f87a912 to
a1f2a6a
Compare
Summary
FeishuStreamingSession.start()throws (e.g. HTTP 400 from CardKit v1 API), the catch block nullsstreamingbut leavesstreamingStartPromisesetstartStreaming()checksstreamingStartPromisefirst, so all futuredeliver()calls silently skip streamingOne-line fix: clear
streamingStartPromisein the catch block alongsidestreaming.Fixes #43322
Changes
extensions/feishu/src/reply-dispatcher.tsstreamingStartPromise = nullin thestart()catch blockextensions/feishu/src/reply-dispatcher.test.tsdeliver()triggers a failingstart(), seconddeliver()creates a new session successfullyCHANGELOG.mdTest plan
pnpm vitest run extensions/feishu/src/reply-dispatcher.test.ts- 23/23 passing (22 existing + 1 new regression test)pnpm formatcleanstart()reject, verifies seconddeliver()creates a fresh streaming session