Closed jiang43605 closed 5 years ago
streaming Boolean - let you get the res object when request connected, default false. alias customResponse
Please delete streaming: true,
in request options.
Hello @jiang43605, we use GitHub issues to trace bugs or discuss plans of Egg.js. So, please don't ask usage questions here. You can try to ask questions on Stack Overflow or CNode.
为什么要删除streaming: true
?我就是要这个功能,你们文档也是这么写的:https://eggjs.org/zh-cn/core/httpclient.html#streaming-boolean
If you set streaming
to true, you will get the raw response object, so you should handle the timeout self.
cc @fengmk2 Is it a bug or feature?
so you should handle the timeout self.
怎么做?上面我提供的代码中,如果超时,将得不到任何返回对象。最外层try...catch...也无法捕捉
...
function startConnectTimer() {
debug('Connect timer ticking, timeout: %d', connectTimeout);
connectTimer = setTimeout(function () {
connectTimer = null;
if (statusCode === -1) {
statusCode = -2;
}
var msg = 'Connect timeout for ' + connectTimeout + 'ms';
var errorName = 'ConnectionTimeoutError';
if (!req.socket) {
errorName = 'SocketAssignTimeoutError';
msg += ', working sockets is full';
}
__err = new Error(msg);
__err.name = errorName;
__err.requestId = reqId;
debug('ConnectTimeout: Request#%d %s %s: %s, connected: %s', reqId, url, __err.name, msg, connected);
// 超时后处理程序
abortRequest();
}, connectTimeout);
}
function startResposneTimer() {
debug('Response timer ticking, timeout: %d', responseTimeout);
responseTimer = setTimeout(function () {
responseTimer = null;
var msg = 'Response timeout for ' + responseTimeout + 'ms';
var errorName = 'ResponseTimeoutError';
__err = new Error(msg);
__err.name = errorName;
__err.requestId = reqId;
debug('ResponseTimeout: Request#%d %s %s: %s, connected: %s', reqId, url, __err.name, msg, connected);
// 超时后处理程序
abortRequest();
}, responseTimeout);
}
...
翻了下源码,发现超时后会交由abortRequest
处理,abortRequest
代码如下:
function abortRequest() {
if (isRequestAborted) {
return;
}
isRequestAborted = true;
debug('Request#%d %s abort, connected: %s', reqId, url, connected);
// it wont case error event when req haven't been assigned a socket yet.
if (!req.socket) {
__err.noSocket = true;
done(__err);
}
// 推测问题所在
// 最后未再调用done(),导致promise处于挂起状态,页面一直处于等待
req.abort();
}
确认一下使用的 urllib 版本,应该已经在 2.31.3 版本之后已修复。 https://github.com/node-modules/urllib/pull/305
好像有点差别,streaming 在 response 就直接返回了,没看怎么处理 timeout
感觉要模拟一个测试用例先返回 header 再返回 body 的场景
好像有点差别,streaming 在 response 就直接返回了,没看怎么处理 timeout
额,不对。如果是 streaming 的参数,timeout 只处理到 header 响应,如果 header 已经返回了,回调函数就已经拿到了 stream 了,urllib 的 timeout 不会再触发的。
嗯,是这个意思
await sendToWormhole(result.res);
不应该写的,超时不会有 result.res。
@fengmk2 嗯,这个写不写跟这个问题确实无关 @dead-horse 升级后问题解决,谢谢!
同样遇到这个问题,关键是egg版本还是老的版本,无法升级
egg 是老版本无所谓,依赖的 urllib 升级就可以了,别锁死版本。
egg 是老版本无所谓,依赖的 urllib 升级就可以了,别锁死版本。
非常感谢,升级了urllib ,成功的解决了问题,服务不再不响应了,能够返回错误信息给前端了。
What happens?
curl设置streaming为true后,如果请求的接口超时,无法捕捉超时错误且浏览器会卡死无限等待
相关环境信息