fix: emit error event if other error events are not listened to

This commit is contained in:
Tony Brix 2021-02-18 22:45:14 -06:00
parent b83008c717
commit bb475ab00f
3 changed files with 119 additions and 3 deletions

View File

@ -1029,9 +1029,9 @@ Client.prototype.connect = function connect () {
self.log.debug('failed to connect after %d attempts', failAfter)
// Communicate the last-encountered error
if (err instanceof ConnectionError) {
self.emit('connectTimeout', err)
self.emitError('connectTimeout', err)
} else if (err.code === 'ECONNREFUSED') {
self.emit('connectRefused', err)
self.emitError('connectRefused', err)
} else {
self.emit('error', err)
}
@ -1277,3 +1277,15 @@ Client.prototype._sendSocket = function _sendSocket (message,
return callback(e)
}
}
Client.prototype.emitError = function emitError (event, err) {
if (event !== 'error' && err && this.listenerCount(event) === 0) {
if (typeof err === 'string') {
err = event + ': ' + err
} else if (err.message) {
err.message = event + ': ' + err.message
}
this.emit('error', err)
}
this.emit(event, err)
}

View File

@ -32,6 +32,9 @@ Object.defineProperties(LDAPError.prototype, {
get: function getMessage () {
return this.lde_message || this.name
},
set: function setMessage (message) {
this.lde_message = message
},
configurable: false
},
dn: {

View File

@ -367,7 +367,7 @@ tap.test('createClient', t => {
)
})
tap.test('exception from bad createClient parameter (issue #418)', t => {
t.test('exception from bad createClient parameter (issue #418)', t => {
try {
// This port number is totally invalid. It will cause the URL parser
// to throw an exception that should be caught.
@ -387,6 +387,9 @@ tap.test('createClient', t => {
],
connectTimeout: 1
})
client.on('connectTimeout', () => {})
client.on('connectError', () => {})
client.on('connectRefused', () => {})
t.equal(client.urls.length, 2)
})
@ -1513,6 +1516,8 @@ tap.test('connection refused', function (t) {
url: `ldap://0.0.0.0:${unusedPortNumber}`
})
client.on('connectRefused', () => {})
client.bind('cn=root', 'secret', function (err, res) {
t.true(err)
t.type(err, Error)
@ -1531,6 +1536,8 @@ tap.test('connection timeout', function (t) {
timeout: 1
})
client.on('connectTimeout', () => {})
let done = false
setTimeout(function () {
@ -1549,3 +1556,97 @@ tap.test('connection timeout', function (t) {
})
})
})
tap.only('emitError', function (t) {
t.test('connectTimeout', function (t) {
getPort().then(function (unusedPortNumber) {
const client = ldap.createClient({
url: `ldap://example.org:${unusedPortNumber}`,
connectTimeout: 1,
timeout: 1
})
const timeout = setTimeout(function () {
throw new Error('LDAPJS waited for the server for too long')
}, 2000)
client.on('error', (err) => {
t.fail(err)
})
client.on('connectTimeout', (err) => {
t.true(err)
t.type(err, Error)
t.equals(err.message, 'connection timeout')
clearTimeout(timeout)
t.end()
})
client.bind('cn=root', 'secret', () => {})
})
})
t.test('connectTimeout to error', function (t) {
getPort().then(function (unusedPortNumber) {
const client = ldap.createClient({
url: `ldap://example.org:${unusedPortNumber}`,
connectTimeout: 1,
timeout: 1
})
const timeout = setTimeout(function () {
throw new Error('LDAPJS waited for the server for too long')
}, 2000)
client.on('error', (err) => {
t.true(err)
t.type(err, Error)
t.equals(err.message, 'connectTimeout: connection timeout')
clearTimeout(timeout)
t.end()
})
client.bind('cn=root', 'secret', () => {})
})
})
t.test('connectRefused', function (t) {
getPort().then(function (unusedPortNumber) {
const client = ldap.createClient({
url: `ldap://0.0.0.0:${unusedPortNumber}`
})
client.on('error', (err) => {
t.fail(err)
})
client.on('connectRefused', (err) => {
t.true(err)
t.type(err, Error)
t.equals(err.message, `connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
t.equals(err.code, 'ECONNREFUSED')
t.end()
})
client.bind('cn=root', 'secret', () => {})
})
})
t.test('connectRefused to error', function (t) {
getPort().then(function (unusedPortNumber) {
const client = ldap.createClient({
url: `ldap://0.0.0.0:${unusedPortNumber}`
})
client.on('error', (err) => {
t.true(err)
t.type(err, Error)
t.equals(err.message, `connectRefused: connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
t.equals(err.code, 'ECONNREFUSED')
t.end()
})
client.bind('cn=root', 'secret', () => {})
})
})
t.end()
})