Skip to content

Commit

Permalink
Catch errors on websocket connections (#940)
Browse files Browse the repository at this point in the history
* Catch errors on websocket connections

Signed-off-by: Matteo Collina <[email protected]>

* fixup

Signed-off-by: Matteo Collina <[email protected]>

Signed-off-by: Matteo Collina <[email protected]>
  • Loading branch information
mcollina committed Jan 10, 2023
1 parent ea1d47f commit b1d0a7f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/subscription-connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ module.exports = class SubscriptionConnection {

this.protocolMessageTypes = getProtocolByName(socket.protocol)
this.socket.on('error', this.handleConnectionClose.bind(this))
this.handleConnection()

// We need a catch here because the socket might be closed before the connection is established
// and we don't want to crash the server. Note that the errors are already
// logged elsewhere @fastify/websocket so there is no need to log them again.
this.handleConnection().catch(noop)
}

async handleConnection () {
Expand Down Expand Up @@ -301,3 +305,5 @@ module.exports = class SubscriptionConnection {
this.handleConnectionClose()
}
}

function noop () {}
32 changes: 32 additions & 0 deletions test/subscription.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const mq = require('mqemitter')
const { EventEmitter } = require('events')
const fastifyWebsocket = require('@fastify/websocket')
const GQL = require('..')
const { once } = require('events')

const FakeTimers = require('@sinonjs/fake-timers')

Expand Down Expand Up @@ -2049,3 +2050,34 @@ test('subscription passes context to its loaders', t => {
})
})
})

test('wrong messages do not crash the server', async (t) => {
const schema = `
type Query {
add(x: Int, y: Int): Int
}
`

const resolvers = {
Query: {
add: async (_, { x, y }) => x + y
}
}

const fastify = Fastify()
fastify.register(GQL, {
schema,
resolvers,
subscription: true
})

await fastify.listen({ port: 0 })

t.teardown(fastify.close.bind(fastify))

const ws = new WebSocket(`ws://127.0.0.1:${fastify.server.address().port}/graphql`, 'graphql-ws')

await once(ws, 'open')
ws._socket.write(Buffer.from([0xa2, 0x00]))
await once(ws, 'close')
})

0 comments on commit b1d0a7f

Please sign in to comment.