Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
fix: better error message when pubsub is not enabled (#1729)
Browse files Browse the repository at this point in the history
If pubsub is disabled there's no `pubsub` property on the libp2p node and we get the error "Cannot read property 'subscribe' of undefined". This is really confusing. This PR detects disabled pubsub and throws an error with a better message.

License: MIT
Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
  • Loading branch information
alanshaw committed Nov 27, 2018
1 parent 008a14d commit 5237dd9
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/core/components/pubsub.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

const promisify = require('promisify-es6')
const setImmediate = require('async/setImmediate')
const errCode = require('err-code')

const errPubsubDisabled = () => {
return errCode(new Error('pubsub experiment is not enabled'), 'ERR_PUBSUB_DISABLED')
}

module.exports = function pubsub (self) {
return {
Expand All @@ -11,6 +16,12 @@ module.exports = function pubsub (self) {
options = {}
}

if (!self._options.EXPERIMENTAL.pubsub) {
return callback
? setImmediate(() => callback(errPubsubDisabled()))
: Promise.reject(errPubsubDisabled())
}

if (!callback) {
return new Promise((resolve, reject) => {
self._libp2pNode.pubsub.subscribe(topic, options, handler, (err) => {
Expand All @@ -26,6 +37,12 @@ module.exports = function pubsub (self) {
},

unsubscribe: (topic, handler, callback) => {
if (!self._options.EXPERIMENTAL.pubsub) {
return callback
? setImmediate(() => callback(errPubsubDisabled()))
: Promise.reject(errPubsubDisabled())
}

self._libp2pNode.pubsub.unsubscribe(topic, handler)

if (!callback) {
Expand All @@ -36,18 +53,30 @@ module.exports = function pubsub (self) {
},

publish: promisify((topic, data, callback) => {
if (!self._options.EXPERIMENTAL.pubsub) {
return setImmediate(() => callback(errPubsubDisabled()))
}
self._libp2pNode.pubsub.publish(topic, data, callback)
}),

ls: promisify((callback) => {
if (!self._options.EXPERIMENTAL.pubsub) {
return setImmediate(() => callback(errPubsubDisabled()))
}
self._libp2pNode.pubsub.ls(callback)
}),

peers: promisify((topic, callback) => {
if (!self._options.EXPERIMENTAL.pubsub) {
return setImmediate(() => callback(errPubsubDisabled()))
}
self._libp2pNode.pubsub.peers(topic, callback)
}),

setMaxListeners (n) {
if (!self._options.EXPERIMENTAL.pubsub) {
throw errPubsubDisabled()
}
self._libp2pNode.pubsub.setMaxListeners(n)
}
}
Expand Down
151 changes: 151 additions & 0 deletions test/core/pubsub.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* eslint max-nested-callbacks: ["error", 8] */
/* eslint-env mocha */
'use strict'

const hat = require('hat')
const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)

const IPFS = require('../../src')
const createTempRepo = require('../utils/create-repo-nodejs')

describe('pubsub disabled', () => {
let ipfs
let repo

before(function (done) {
this.timeout(20 * 1000)

repo = createTempRepo()
ipfs = new IPFS({
repo,
config: {
Addresses: {
Swarm: []
}
},
preload: {
enabled: false
},
EXPERIMENTAL: {
pubsub: false
}
})

ipfs.on('ready', done)
})

after((done) => ipfs.stop(done))

after((done) => repo.teardown(done))

it('should not allow subscribe if disabled', done => {
const topic = hat()
const handler = () => done(new Error('unexpected message'))
ipfs.pubsub.subscribe(topic, handler, (err) => {
expect(err).to.exist()
expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
done()
})
})

it('should not allow subscribe if disabled (promised)', async () => {
try {
const topic = hat()
const handler = () => { throw new Error('unexpected message') }
await ipfs.pubsub.subscribe(topic, handler)
} catch (err) {
return expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
}
throw new Error('expected error to be thrown')
})

it('should not allow unsubscribe if disabled', done => {
const topic = hat()
const handler = () => done(new Error('unexpected message'))
ipfs.pubsub.unsubscribe(topic, handler, (err) => {
expect(err).to.exist()
expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
done()
})
})

it('should not allow unsubscribe if disabled (promised)', async () => {
try {
const topic = hat()
const handler = () => { throw new Error('unexpected message') }
await ipfs.pubsub.unsubscribe(topic, handler)
} catch (err) {
return expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
}
throw new Error('expected error to be thrown')
})

it('should not allow publish if disabled', done => {
const topic = hat()
const msg = Buffer.from(hat())
ipfs.pubsub.publish(topic, msg, (err) => {
expect(err).to.exist()
expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
done()
})
})

it('should not allow publish if disabled (promised)', async () => {
try {
const topic = hat()
const msg = Buffer.from(hat())
await ipfs.pubsub.publish(topic, msg)
} catch (err) {
return expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
}
throw new Error('expected error to be thrown')
})

it('should not allow ls if disabled', done => {
ipfs.pubsub.ls((err) => {
expect(err).to.exist()
expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
done()
})
})

it('should not allow ls if disabled (promised)', async () => {
try {
await ipfs.pubsub.ls()
} catch (err) {
return expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
}
throw new Error('expected error to be thrown')
})

it('should not allow peers if disabled', done => {
const topic = hat()
ipfs.pubsub.peers(topic, (err) => {
expect(err).to.exist()
expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
done()
})
})

it('should not allow peers if disabled (promised)', async () => {
try {
const topic = hat()
await ipfs.pubsub.peers(topic)
} catch (err) {
return expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
}
throw new Error('expected error to be thrown')
})

it('should not allow setMaxListeners if disabled', async () => {
try {
await ipfs.pubsub.setMaxListeners(100)
} catch (err) {
return expect(err.code).to.equal('ERR_PUBSUB_DISABLED')
}
throw new Error('expected error to be thrown')
})
})

0 comments on commit 5237dd9

Please sign in to comment.