Skip to content

Commit

Permalink
fix(client): Don't complete after connection error
Browse files Browse the repository at this point in the history
  • Loading branch information
enisdenjo committed Oct 20, 2021
1 parent 27754b2 commit 5f829c3
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
86 changes: 86 additions & 0 deletions src/__tests__/client.ts
Expand Up @@ -369,6 +369,33 @@ it('should not call complete after subscription error', async () => {
}, 20);
});

it('should not call complete after connection error', async () => {
const { url, waitForClient } = await startTServer();

const client = createClient({
url,
lazy: false,
retryAttempts: 0,
});

const sub = tsubscribe(client, {
query: '{ hello }',
});

// kick off immediately
await waitForClient((client) => {
client.close();
});

// report error
await sub.waitForError();

// but not complete
await sub.waitForComplete(() => {
fail("shouldn't have completed");
}, 20);
});

it('should use a custom JSON message reviver function', async () => {
const { url } = await startTServer();

Expand Down Expand Up @@ -539,6 +566,65 @@ it('should report close error even if complete message followed', async (done) =
);
});

it('should report close error even if complete message followed', async (done) => {
expect.assertions(4);

const { url, server } = await startRawServer();

server.on('connection', (socket) => {
socket.on('message', (data) => {
const msg = parseMessage(String(data));

// acknowledge conneciton
if (msg.type === MessageType.ConnectionInit)
socket.send(stringifyMessage({ type: MessageType.ConnectionAck }));

// respond with a malformed error message and a complete
if (msg.type === MessageType.Subscribe) {
socket.send(
JSON.stringify({
id: msg.id,
type: MessageType.Error,
payload: 'malformed',
}),
);
socket.send(
stringifyMessage({ id: msg.id, type: MessageType.Complete }),
);
}
});
});

const client = createClient({
url,
lazy: false,
retryAttempts: 0,
onNonLazyError: noop,
on: {
closed: (err) => {
expect((err as CloseEvent).code).toBe(CloseCode.BadRequest);
expect((err as CloseEvent).reason).toBe('Invalid message');
},
},
});

client.subscribe(
{
query: 'notaquery',
},
{
next: noop,
error: (err) => {
expect((err as CloseEvent).code).toBe(CloseCode.BadRequest);
expect((err as CloseEvent).reason).toBe('Invalid message');
client.dispose();
done();
},
complete: noop,
},
);
});

describe('ping/pong', () => {
it('should respond with a pong to a ping', async () => {
expect.assertions(1);
Expand Down
5 changes: 4 additions & 1 deletion src/client.ts
Expand Up @@ -883,7 +883,10 @@ export function createClient(options: ClientOptions): Client {
}
}
})()
.catch(sink.error) // rejects on close events and errors
.catch((err) => {
(errored = true), (done = true);
sink.error(err);
}) // rejects on close events and errors
.then(() => {
// delivering either an error or a complete terminates the sequence
if (!errored) sink.complete();
Expand Down

0 comments on commit 5f829c3

Please sign in to comment.