Commit adaa4fd
authored
fix(frontend): resolve stale closure in chatHistory updateCurrentSession (#1294)
## Root cause
`updateCurrentSession` in `useChatHistory.ts` read `historyState.currentSessionId` from its **stale closure** for the early-return guard:
```typescript
// BEFORE — stale closure
const updateCurrentSession = useCallback(
(messages: ChatMessage[]) => {
if (!historyState.currentSessionId) return; // captures outer historyState
setHistoryState((prev) => { … });
},
[historyState.currentSessionId],
);
```
If `currentSessionId` changed between renders (e.g. the user opened a different session) before the callback was recreated by React, the guard could read the wrong value — silently skipping the update and causing the previous session's messages to be lost.
## Fix (`src/hooks/useChatHistory.ts`)
Move the guard inside the `setHistoryState` functional updater, where `prev` is always the fresh committed state provided by React — no closure involved:
```typescript
// AFTER — always reads fresh state via prev
const updateCurrentSession = useCallback(
(messages: ChatMessage[]) => {
setHistoryState((prev) => {
if (!prev.currentSessionId) return prev; // fresh, never stale
…
});
},
[], // no dependency on historyState needed
);
```
## Regression tests (`src/hooks/useChatHistory.test.ts`)
Two tests added:
1. Verifies the updater applies messages to the session identified by `prev.currentSessionId`, even when a stale outer value would point to a different session.
2. Verifies the updater returns `prev` unchanged when `prev.currentSessionId` is `null`.
Closes #12231 parent 598a802 commit adaa4fd
2 files changed
Lines changed: 59 additions & 6 deletions
Lines changed: 54 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
106 | 106 | | |
107 | 107 | | |
108 | 108 | | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 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 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | | - | |
80 | | - | |
81 | 79 | | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
82 | 84 | | |
83 | 85 | | |
84 | 86 | | |
| |||
90 | 92 | | |
91 | 93 | | |
92 | 94 | | |
93 | | - | |
94 | 95 | | |
95 | 96 | | |
96 | 97 | | |
| |||
103 | 104 | | |
104 | 105 | | |
105 | 106 | | |
106 | | - | |
| 107 | + | |
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| |||
0 commit comments