admin管理员组文章数量:1402842
So, I'm making this request to a server and I set a timeout and I want to handle the timeout event, but I also want to handle the 'abort' event and differ one for another. I managed to do it with a quick fix, but I wanted to know if there is a better way to do it. The code looks like this:
makeRequest = function(json, cb){
var requestError
request({
url: REQUEST_URL,
json: json,
timeout: 3000,
headers: {
'Content-Type': 'application/json'
}
}, function(err, res, body){
if(err) requestError = err
else cb(null, res, body)
}).on('abort', function(){
setTimeout(function({
if(requestError != 'ETIMEDOUT') cb(httpStatusCode.REQUEST_TIMEDOUT)
else cb(httpStatusCode.REQUEST_ABORTED
}, 1000)
})
}
I noticed that in the timeout event both the 'abort' event is triggered and the request callback is called, in this order, so I used the setTimeout function to wait for the request callback and than handle the error in the 'abort' listener. This seems like a dumb way to do it and I searched online and did not find a way yo handle only the callback event. I also noticed that the timeout triggers the on.('error', function(err){}) event, where I can handle the error, but it also calls the on.('abort', function(){}) event and I end up calling the main callback (cb) two times, crashing my application.
Is there a way I can have an event ONLY for the timeout and one ONLY for the abort, so I don't have to use setTimeout?
Or is there any property in my req object that I can check to see if that request timed out or not?
Or do you have any other suggestion to fix my problem in a less ugly way?
I'm using nodejs 0.12.2 and request 2.55.0 Thanks!
So, I'm making this request to a server and I set a timeout and I want to handle the timeout event, but I also want to handle the 'abort' event and differ one for another. I managed to do it with a quick fix, but I wanted to know if there is a better way to do it. The code looks like this:
makeRequest = function(json, cb){
var requestError
request({
url: REQUEST_URL,
json: json,
timeout: 3000,
headers: {
'Content-Type': 'application/json'
}
}, function(err, res, body){
if(err) requestError = err
else cb(null, res, body)
}).on('abort', function(){
setTimeout(function({
if(requestError != 'ETIMEDOUT') cb(httpStatusCode.REQUEST_TIMEDOUT)
else cb(httpStatusCode.REQUEST_ABORTED
}, 1000)
})
}
I noticed that in the timeout event both the 'abort' event is triggered and the request callback is called, in this order, so I used the setTimeout function to wait for the request callback and than handle the error in the 'abort' listener. This seems like a dumb way to do it and I searched online and did not find a way yo handle only the callback event. I also noticed that the timeout triggers the on.('error', function(err){}) event, where I can handle the error, but it also calls the on.('abort', function(){}) event and I end up calling the main callback (cb) two times, crashing my application.
Is there a way I can have an event ONLY for the timeout and one ONLY for the abort, so I don't have to use setTimeout?
Or is there any property in my req object that I can check to see if that request timed out or not?
Or do you have any other suggestion to fix my problem in a less ugly way?
I'm using nodejs 0.12.2 and request 2.55.0 Thanks!
Share Improve this question edited Jul 7, 2015 at 1:31 Thiago Loddi asked Jul 7, 2015 at 1:04 Thiago LoddiThiago Loddi 2,3405 gold badges23 silver badges36 bronze badges 1- correct me if I am wrong, but isn't the abort because of the timeout? – mido Commented Jul 7, 2015 at 2:10
1 Answer
Reset to default 2One great thing about open source is that you can always just go look at the code for the module and see how it works.
If you want the error, then just listen for .on('error', function(err) {})
. The error will be passed there. The .on('abort', function() {})
event does not tell you why it was aborted. But, as you can see from the relevant source code for the request module, the error
event is always sent right after the abort
event and it will have e.code
set to ETIMEDOUT
.
Here's a copy of some of the relevant source code for when .abort()
is called where you can see it triggers the error event right afterwards:
if (self.timeout && !self.timeoutTimer) {
var timeout = self.timeout < 0 ? 0 : self.timeout
self.timeoutTimer = setTimeout(function () {
self.abort()
var e = new Error('ETIMEDOUT')
e.code = 'ETIMEDOUT'
self.emit('error', e)
}, timeout)
// Set additional timeout on socket - in case if remote
// server freeze after sending headers
if (self.req.setTimeout) { // only works on node 0.6+
self.req.setTimeout(timeout, function () {
if (self.req) {
self.req.abort()
var e = new Error('ESOCKETTIMEDOUT')
e.code = 'ESOCKETTIMEDOUT'
self.emit('error', e)
}
})
}
}
So, it seems you can ignore the abort
event and just listen for the error
event and just call your callback on the error
event.
If your code is such that it messes up if the callback is called with an error more than once (which it sounds like it is), then you can change your makeRequest()
function so that it never calls the callback more than once too.
本文标签: javascriptHow to handle timeout using request with nodejsStack Overflow
版权声明:本文标题:javascript - How to handle timeout using request with nodejs - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744291029a2599114.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论