Reputation: 15
I have to scrape a web page for a key to use later as a cookie. That part works. But because the request is async the error is not handled. I want to make sure the error is passed along the middleware chain. But I can't get my brain around this one. Thanks for helping.
app.use('/', makeLoginCookie, function (req, res, next){
console.log('My app.use() starts here.');
//console.log('makeLoginCookie: %s', err);
next();
});
And here's the function
function makeLoginCookie(req, res, next) {
httpOptions = {
url: site.url,
headers: {
Cookie: null
}
}
// Get HIDDEN key, build login cookie
request(httpOptions, function(error, response, body) {
if (!error && response.statusCode == 200) {
//console.log(body)
var match = body.match( /\<INPUT TYPE=HIDDEN id=\"key\", value=\"([0-9a-f]+)\"\>/i );
var key = match[1]
var encrypted = sha1(key + site.username + site.password);
loginCookie = "username=" + key + ";password=" + encrypted;
next();
} else {
console.log("Connect failed %s" , error);
//err = new Error("Can't connect");
next();
}
});
};
Upvotes: 1
Views: 1047
Reputation: 15
There must have been some error elsewhere in my code because this works as expected now.
} else {
console.log("Connect failed %s" , error);
err = new Error("Can't connect");
next(err);
}
Upvotes: 0
Reputation: 56
I would use promises (Q library) in order to resolve this, and for another things too, specially for web scraping. Your "makeLoginCookie" function could return a deferred.promise and, when the request fails, reject it with the error.
Edit 1: I recommend this great video that explains how to work properly with async code https://www.youtube.com/watch?v=obaSQBBWZLk. It could help you with this and another stuff.
Edit 2: Using promises would be like this, see if it helps you:
var Q = require("q");
app.use('/', function (req, res, next) {
// This part, we will call your function "makeLoginCookie"
makeLoginCookie().then(function(){
// This is called when your function RESOLVES the promise
// Here you could log or do some stuff...
// Then, go next...
next();
}, function(error){
// This is called when your function REJECTS the promise
console.log("Connect failed %s" , error);
// And then, handle the error, like stopping the request and sending an error:
res.status(400).json({errorMessage: error});
})
}, function (req, res, next){
console.log('My app.use() starts here.');
next();
});
// Removed parameters from function
function makeLoginCookie() {
// This is the object that will return a promise
var deferred = Q.defer();
httpOptions = {
url: site.url,
headers: {
Cookie: null
}
}
// Get HIDDEN key, build login cookie
request(httpOptions, function(error, response, body) {
if (!error && response.statusCode == 200) {
//console.log(body)
var match = body.match( /\<INPUT TYPE=HIDDEN id=\"key\", value=\"([0-9a-f]+)\"\>/i );
var key = match[1]
var encrypted = sha1(key + site.username + site.password);
loginCookie = "username=" + key + ";password=" + encrypted;
// Instead of using next(), RESOLVE your promise
// next();
deferred.resolve(); // You can pass some data into it..
} else {
// Instead of using next(), REJECT your promise
// next();
deferred.reject(error); // You can pass some data into it, like an error object or string...
}
});
// Promise that something will be fulfilled or reject later
return deferred.promise;
};
Upvotes: 0
Reputation: 48536
Refer to Express Error handling, you can use next(err);
to pass error in Express
. Here is one good link.
Upvotes: 3