我知道SO上涉及UnhandledPromiseRejectionWarning
的问题的现有答案,但找不到的似乎与我的案例充分匹配。基本上,我以为我知道如何处理承诺。但是这个案子让我疯了,所以我想在这里寻求一些支持:如何摆脱这种警告?
我正在NodeJS中实现一些可写流,其实现为_write()
:
_write( data, encoding, doneFn ) {
Promise.race( [
this.getSocket(),
new Promise( ( resolve, reject ) => {
setTimeout( reject, 1000, Object.assign( new Error( `timeout on trying to connect w/ ${this.address}` ), { code: "ECONNREFUSED" } ) );
} ),
] )
.then( socket => {
if ( socket ) {
return new Promise( ( resolve, reject ) => {
socket.once( "error", reject );
socket.write( data, encoding, () => {
socket.removeListener( "error", reject );
resolve();
} );
} );
}
} )
.then( doneFn )
.catch( error => {
const { address } = this;
switch ( error.code ) {
case "EPIPE" :
case "ECONNRESET" :
Log( `lost connection w/ ${address.id}` );
break;
case "ECONNREFUSED" :
Log( `failed to connect w/ ${address.id}` );
break;
}
console.log( "error is", error.message );
doneFn( error );
} );
}
当我测试此代码以便在超时时正确发出错误时,我会得到神秘的UnhandledPromiseRejectionWarning
。
error is timeout on trying to connect w/ /ip4/127.0.0.1/tcp/1
(node:5052) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: timeout on trying to connect w/ /ip4/127.0.0.1/tcp/1
由于_write()
无法通过设计工作,我很确定这个警告是由于此处给出的代码所致。但我无法弄清楚如何摆脱警告。即使明确地附加catch-handler也没有压制它。
更新:代码已经过重构和重新测试。尽管如此仍会记录拒绝警告。我首先使用的是NodeJS 6.11,但这次是8.11。
答案 0 :(得分:0)
坦率地说,你的代码非常混乱。在尝试调试上述问题之前,您最好重写这样的代码。
_write( data, encoding, doneFn ) {
Promise.race( [
this.getSocket(),
/* This below code should better be handled within method this.getSocket so we won't need to use Promise.race */
new Promise((resolve, reject) => {
setTimeout( reject, 1000, Object.assign( new Error( `timeout on trying to connect w/ ${this.address}` ), { code: "ECONNREFUSED" } ) );
}),
] )
.then( socket => {
return socket && new Promise( ( resolve, reject ) => {
socket.once( "error", reject );
socket.write( data, encoding, () => {
socket.removeListener( "error", reject );
resolve();
} );
} );
} )
.then(doneFn)
.catch(error => {
const { address } = this;
switch ( error.code ) {
case "EPIPE" :
case "ECONNRESET" :
Log( `lost connection w/ ${address.id}` );
break;
case "ECONNREFUSED" :
Log( `failed to connect w/ ${address.id}` );
break;
}
doneFn( error );
});
}
答案 1 :(得分:0)
看起来流实施存在问题w / Promise.race()
。
我试图将代码细分为基本模式:
function someHandler( doneFn ) {
const toBeResolvedLate = new Promise( ( resolve, reject ) => {
setTimeout( resolve, 5000 );
} );
const toBeRejectedEarly = new Promise( ( resolve, reject ) => {
setTimeout( reject, 1000, new Error( "timeout" ) );
} );
Promise.race( [
toBeRejectedEarly,
toBeResolvedLate,
] )
.then( doneFn )
.catch( error => {
doneFn( error );
} );
}
someHandler( ( ...args ) => {
console.log( "directly:", args );
} );
const { Writable } = require( "stream" );
const stream = new Writable( {
write: function( a, b, done ) {
someHandler( ( ...args ) => {
console.log( "in _write:", args );
done( ...args );
} );
},
} );
stream.write( Buffer.from( "chunk" ) );
结果我得到了这个:
directly: [ Error: timeout
at Promise (...\scratch_2.es6:6:30)
at new Promise (<anonymous>)
at someHandler (...\scratch_2.es6:5:29)
at Object.<anonymous> (...\scratch_2.es6:20:2)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10) ]
in _write: [ Error: timeout
at Promise (...\scratch_2.es6:6:30)
at new Promise (<anonymous>)
at someHandler (...\scratch_2.es6:5:29)
at Writable.write [as _write] (...\scratch_2.es6:29:4)
at doWrite (_stream_writable.js:397:12)
at writeOrBuffer (_stream_writable.js:383:5)
at Writable.write (_stream_writable.js:290:11)
at Object.<anonymous> (...\scratch_2.es6:36:9)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10) ]
(node:3288) UnhandledPromiseRejectionWarning: Error: timeout
at Promise (...\scratch_2.es6:6:30)
at new Promise (<anonymous>)
at someHandler (...\scratch_2.es6:5:29)
at Writable.write [as _write] (...\scratch_2.es6:29:4)
at doWrite (_stream_writable.js:397:12)
at writeOrBuffer (_stream_writable.js:383:5)
at Writable.write (_stream_writable.js:290:11)
at Object.<anonymous> (...\scratch_2.es6:36:9)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
(node:3288) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3288) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
如果我省略了尝试写入块的最后一行代码,那么第二个堆栈跟踪以及UnhandledPromiseRejectionWarning
- 东西就会消失。