Skip to content
This repository was archived by the owner on May 14, 2024. It is now read-only.

Commit 1c9643a

Browse files
authored
Merge branch 'master' into dependabot/npm_and_yarn/marked-2.0.0
2 parents 0379bbb + f247fba commit 1c9643a

File tree

4 files changed

+142
-3
lines changed

4 files changed

+142
-3
lines changed

docs/client.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ The code to create a new client looks like:
2020
url: ['ldap://127.0.0.1:1389', 'ldap://127.0.0.2:1389']
2121
});
2222

23+
client.on('error', (err) => {
24+
// handle connection error
25+
})
26+
2327
You can use `ldap://` or `ldaps://`; the latter would connect over SSL (note
2428
that this will not use the LDAP TLS extended operation, but literally an SSL
2529
connection to port 636, as in LDAP v2). The full set of options to create a
@@ -70,6 +74,25 @@ more sophisticated control, you can provide an Object with the properties
7074
`failAfter` (default: `Infinity`).
7175
After the reconnect you maybe need to [bind](#bind) again.
7276

77+
## Client events
78+
79+
The client is an `EventEmitter` and can emit the following events:
80+
81+
|Event |Description |
82+
|---------------|----------------------------------------------------------|
83+
|error |General error |
84+
|connectRefused |Server refused connection. Most likely bad authentication |
85+
|connectTimeout |Server timeout |
86+
|connectError |Socket connection error |
87+
|setupError |Setup error after successful connection |
88+
|socketTimeout |Socket timeout |
89+
|resultError |Search result error |
90+
|timeout |Search result timeout |
91+
|destroy |After client is disconnected |
92+
|end |Socket end event |
93+
|close |Socket closed |
94+
|connect |Client connected |
95+
|idle |Idle timeout reached |
7396

7497
## Common patterns
7598

lib/client/client.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,9 +1029,9 @@ Client.prototype.connect = function connect () {
10291029
self.log.debug('failed to connect after %d attempts', failAfter)
10301030
// Communicate the last-encountered error
10311031
if (err instanceof ConnectionError) {
1032-
self.emit('connectTimeout', err)
1032+
self.emitError('connectTimeout', err)
10331033
} else if (err.code === 'ECONNREFUSED') {
1034-
self.emit('connectRefused', err)
1034+
self.emitError('connectRefused', err)
10351035
} else {
10361036
self.emit('error', err)
10371037
}
@@ -1277,3 +1277,15 @@ Client.prototype._sendSocket = function _sendSocket (message,
12771277
return callback(e)
12781278
}
12791279
}
1280+
1281+
Client.prototype.emitError = function emitError (event, err) {
1282+
if (event !== 'error' && err && this.listenerCount(event) === 0) {
1283+
if (typeof err === 'string') {
1284+
err = event + ': ' + err
1285+
} else if (err.message) {
1286+
err.message = event + ': ' + err.message
1287+
}
1288+
this.emit('error', err)
1289+
}
1290+
this.emit(event, err)
1291+
}

lib/errors/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Object.defineProperties(LDAPError.prototype, {
3232
get: function getMessage () {
3333
return this.lde_message || this.name
3434
},
35+
set: function setMessage (message) {
36+
this.lde_message = message
37+
},
3538
configurable: false
3639
},
3740
dn: {

test/client.test.js

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ tap.test('createClient', t => {
367367
)
368368
})
369369

370-
tap.test('exception from bad createClient parameter (issue #418)', t => {
370+
t.test('exception from bad createClient parameter (issue #418)', t => {
371371
try {
372372
// This port number is totally invalid. It will cause the URL parser
373373
// to throw an exception that should be caught.
@@ -387,6 +387,9 @@ tap.test('createClient', t => {
387387
],
388388
connectTimeout: 1
389389
})
390+
client.on('connectTimeout', () => {})
391+
client.on('connectError', () => {})
392+
client.on('connectRefused', () => {})
390393

391394
t.equal(client.urls.length, 2)
392395
})
@@ -1513,6 +1516,8 @@ tap.test('connection refused', function (t) {
15131516
url: `ldap://0.0.0.0:${unusedPortNumber}`
15141517
})
15151518

1519+
client.on('connectRefused', () => {})
1520+
15161521
client.bind('cn=root', 'secret', function (err, res) {
15171522
t.true(err)
15181523
t.type(err, Error)
@@ -1531,6 +1536,8 @@ tap.test('connection timeout', function (t) {
15311536
timeout: 1
15321537
})
15331538

1539+
client.on('connectTimeout', () => {})
1540+
15341541
let done = false
15351542

15361543
setTimeout(function () {
@@ -1549,3 +1556,97 @@ tap.test('connection timeout', function (t) {
15491556
})
15501557
})
15511558
})
1559+
1560+
tap.only('emitError', function (t) {
1561+
t.test('connectTimeout', function (t) {
1562+
getPort().then(function (unusedPortNumber) {
1563+
const client = ldap.createClient({
1564+
url: `ldap://example.org:${unusedPortNumber}`,
1565+
connectTimeout: 1,
1566+
timeout: 1
1567+
})
1568+
1569+
const timeout = setTimeout(function () {
1570+
throw new Error('LDAPJS waited for the server for too long')
1571+
}, 2000)
1572+
1573+
client.on('error', (err) => {
1574+
t.fail(err)
1575+
})
1576+
client.on('connectTimeout', (err) => {
1577+
t.true(err)
1578+
t.type(err, Error)
1579+
t.equals(err.message, 'connection timeout')
1580+
clearTimeout(timeout)
1581+
t.end()
1582+
})
1583+
1584+
client.bind('cn=root', 'secret', () => {})
1585+
})
1586+
})
1587+
1588+
t.test('connectTimeout to error', function (t) {
1589+
getPort().then(function (unusedPortNumber) {
1590+
const client = ldap.createClient({
1591+
url: `ldap://example.org:${unusedPortNumber}`,
1592+
connectTimeout: 1,
1593+
timeout: 1
1594+
})
1595+
1596+
const timeout = setTimeout(function () {
1597+
throw new Error('LDAPJS waited for the server for too long')
1598+
}, 2000)
1599+
1600+
client.on('error', (err) => {
1601+
t.true(err)
1602+
t.type(err, Error)
1603+
t.equals(err.message, 'connectTimeout: connection timeout')
1604+
clearTimeout(timeout)
1605+
t.end()
1606+
})
1607+
1608+
client.bind('cn=root', 'secret', () => {})
1609+
})
1610+
})
1611+
1612+
t.test('connectRefused', function (t) {
1613+
getPort().then(function (unusedPortNumber) {
1614+
const client = ldap.createClient({
1615+
url: `ldap://0.0.0.0:${unusedPortNumber}`
1616+
})
1617+
1618+
client.on('error', (err) => {
1619+
t.fail(err)
1620+
})
1621+
client.on('connectRefused', (err) => {
1622+
t.true(err)
1623+
t.type(err, Error)
1624+
t.equals(err.message, `connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
1625+
t.equals(err.code, 'ECONNREFUSED')
1626+
t.end()
1627+
})
1628+
1629+
client.bind('cn=root', 'secret', () => {})
1630+
})
1631+
})
1632+
1633+
t.test('connectRefused to error', function (t) {
1634+
getPort().then(function (unusedPortNumber) {
1635+
const client = ldap.createClient({
1636+
url: `ldap://0.0.0.0:${unusedPortNumber}`
1637+
})
1638+
1639+
client.on('error', (err) => {
1640+
t.true(err)
1641+
t.type(err, Error)
1642+
t.equals(err.message, `connectRefused: connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
1643+
t.equals(err.code, 'ECONNREFUSED')
1644+
t.end()
1645+
})
1646+
1647+
client.bind('cn=root', 'secret', () => {})
1648+
})
1649+
})
1650+
1651+
t.end()
1652+
})

0 commit comments

Comments
 (0)