|
|
@@ -99,6 +99,29 @@ describe('Session open', () => {
|
|
|
expect(api.followStarts).toHaveLength(2)
|
|
|
})
|
|
|
|
|
|
+ it('lands a packed live record in openState=error instead of crashing the stream loop', async () => {
|
|
|
+ const { api, session } = makeSession()
|
|
|
+ api.onHistory = () => histResponse(plainTurn(0, 0, 'a', 'b'))
|
|
|
+ await session.open()
|
|
|
+ expect(session.getSnapshot().openState).toBe('open')
|
|
|
+
|
|
|
+ // The live tail may carry only events; a packed record breaks that contract.
|
|
|
+ await api.pushFollow(SID, {
|
|
|
+ type: 'chunks',
|
|
|
+ event: {
|
|
|
+ type: 'chunkrow/text-chunks',
|
|
|
+ seq: 6,
|
|
|
+ time: 6,
|
|
|
+ data: { turn: 1, step: 1, index: 0, texts: ['a'], dt: [] },
|
|
|
+ },
|
|
|
+ } as never)
|
|
|
+
|
|
|
+ await vi.waitFor(() => { expect(session.getSnapshot().openState).toBe('error') })
|
|
|
+ expect(session.getSnapshot().openError).toMatchObject({
|
|
|
+ code: 'gateway/internal', message: 'session live stream emitted a packed history record',
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
it('lands a Gateway-marked stream failure in openState=error', async () => {
|
|
|
const { api, session } = makeSession()
|
|
|
api.onHistory = () => Promise.reject(new Error('socket died'))
|