在由NodeJS运行的PM2服务器中,我使用npm模块“ldap认证”对用户进行身份验证。
const { authenticate } = require('ldap-authentication');
...
try {
const auth = await authenticate(options);
return auth;
} catch(err){
return err;
}当凭据正常时,它可以正常工作。
当凭据错误时,函数抛出一个可以捕获并易于处理的正确错误。
当没有连接并出现"getaddrinfo ENOTFOUND“错误时,就会出现问题,
Error: getaddrinfo ENOTFOUND xxx.xxx.corp
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26)由于代码崩溃而没有捕获任何错误,导致不可接受的问题(尽管PM2重新启动代码)。我需要处理可能中断的连接,并避免服务器崩溃。
它看起来不是从异步函数捕获错误的问题,因为这个函数的其他类型的错误都会被捕获。注意此链接似乎是这个特定模块中这个特定错误的一个问题。
有什么想法吗?
发布于 2020-10-09 17:10:48
不幸的是,这似乎是底层ldapjs库中的错误。ENOTFOUND需要在Socket.on('error')中进行处理,但是直到调用Socket.connect()之后才会设置,因此在发生DNS错误时它是不可用的。
您可以在这里看到代码,https://github.com/ldapjs/node-ldapjs/blob/master/lib/client/client.js#L827
if (server && server.secure) {
socket = tls.connect(port, host, self.tlsOptions)
socket.once('secureConnect', onConnect)
} else {
socket = net.connect(port, host)
socket.once('connect', onConnect)
}
socket.once('error', onResult)要处理DNS错误,需要如下所示
// reference to the socket
let socket;
if (server && server.secure) {
// create TLS socket and connection handler
socket = new tls.TLSSocket(self.tlsOptions);
socket.once('secureConnect', onConnect)
} else {
// create net socket and connection handler
socket = new net.Socket();
socket.once('connect', onConnect)
}
// set up error handler - including DNS
socket.once('error', onResult)
// connect the socket after we have an error handler
socket.connect(port, host)我还没有进行测试,但是向您在这里使用的模块添加一个错误处理程序也是可行的- https://github.com/shaozi/ldap-authentication/blob/master/index.js#L8
var client = ldap.createClient(ldapOpts)
client.on('error', (err) = { /* set up before connect */ });除了提交一个PR来修复底层库之外,我最好的想法是在尝试连接- 回调之前使用一个包装器进行DNS查找。
const dns = require('dns');
const auth = await new Promise((resolve, reject) => {
dns.lookup('xxx.xxx.corp', (err, address, family) => {
// console.log('address: %j family: IPv%s', address, family));
if (err) {
return reject(err);
}
return resolve(authenticate(options));
}
});发布于 2020-10-13 15:51:07
对调用函数中的错误凭据错误和通信中断情况进行一些修改。
如果出现错误,则抛出拒绝,如果凭据糟糕,则不使用param就可以解决。
return new Promise((resolve, reject) => {
dns.lookup('xxx.xxx.corp', async (err, address, family) => {
if (err) {
return reject(err);
};
try {
const x = await(authenticate(options));
return resolve(x);
} catch(err){
return resolve();
}
});
});https://stackoverflow.com/questions/64283656
复制相似问题