'Node-request - How to determine if an error occurred during the request?
I'm trying to leverage the node-request module, but the documentation isn't that great. If I make a request to a valid resource and pipe it to a Writable Stream, everything works fine. However, if I make a request to an invalid object, the Writable Stream is still created. Example, take the following snippet:
var x = request("http://localhost:3000/foo.jpg");
var st = fs.createWriteStream("foo.jpg");
x.pipe(st);
If the foo.jpg resource exists on the server, the data is piped to the stream, and it creates the file fine on the server. However, if foo.jpg does not exist on the server, a blank container file is still created. There appears to be no error event or anything that can be leveraged to determine if the request returned a 404. I've tried something like the following:
var x = request("http://localhost:3000/foo.jpg", function(err, response, body) {
if(response.statusCode === 200) {
// Success
var st = fs.createWriteStream("foo.jpg");
x.pipe(st);
}
});
And also:
request("http://localhost:3000/foo.jpg", function(err, response, body) {
if(response.statusCode === 200) {
// Success
var x = response.request;
var st = fs.createWriteStream("foo.jpg");
x.pipe(st);
}
});
To no avail. The idea is pretty simple; I just want to copy a file identified by the URL to the local server. If the request is invalid (404, etc), don't pipe the file; if the request is valid, pipe the file. Any suggestions?
Solution 1:[1]
The way I ended up succeeding with new Streams in node:
function doQuery(){
var r = request(url)
r.pause()
r.on('response', function (resp) {
if(resp.statusCode === 200){
r.pipe(new WritableStream()) //pipe to where you want it to go
r.resume()
}else{ }
})
}
This is really flexible - if you want to retry, you can call the function recursively with setTimeout
function doQuery(){
var r = request(url)
r.pause()
r.on('response', function (resp) {
if(resp.statusCode === 200){
r.pipe(new WritableStream()) //pipe to where you want it to go
r.resume()
}else{
setTimeout(doQuery,1000)
}
})
}
Solution 2:[2]
@Mikeal solution looks great, but may have some problem with the piping (first few bytes can be missed). Hee is an updated code:
var r = request(url)
r.pipe(new WritableStream());
r.on('response', function (resp) {
resp.headers
resp.statusCode
// Handle error case and remove your writablestream if need be.
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | naugtur |
| Solution 2 | Neamar |
