Skip to content

Commit

Permalink
Spread improved error handling love. Fix google example
Browse files Browse the repository at this point in the history
  • Loading branch information
bnoguchi committed Apr 22, 2012
1 parent 4b03a35 commit c501bc9
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 66 deletions.
2 changes: 1 addition & 1 deletion example/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ everyauth.linkedin
everyauth.google
.appId(conf.google.clientId)
.appSecret(conf.google.clientSecret)
.scope('https://www.google.com/m8/feeds/')
.scope('https://www.googleapis.com/auth/userinfo.profile https://www.google.com/m8/feeds/')
.findOrCreateUser( function (sess, accessToken, extra, googleUser) {
googleUser.refreshToken = extra.refresh_token;
googleUser.expiresIn = extra.expires_in;
Expand Down
22 changes: 19 additions & 3 deletions lib/modules/37signals.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,23 @@ oauthModule.submodule('37signals')
})
return p;
})

.convertErr( function (err) {
return new Error(err.data);
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var _37sigResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
_37sigResponse.statusCode
, _37sigResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
console.error(err);
throw new Error('Unsupported error type');
}
});
9 changes: 5 additions & 4 deletions lib/modules/everymodule.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ var everyModule = module.exports = {
*/
, breakTo: function (sequenceName) {
// TODO Garbage collect the abandoned sequence
var seq = this._stepSequences[sequenceName]
, args = Array.prototype.slice.call(arguments, 1);
var seq = this._stepSequences[sequenceName];
if (!seq) {
throw new Error('You are trying to break to a sequence named `' + sequenceName + '`, but there is no sequence with that name in the auth module, `' + this.name + '`.');
}
var args = Array.prototype.slice.call(arguments, 1);
seq = seq.materialize();
seq.initialArgs = args;
throw seq;
Expand Down Expand Up @@ -355,10 +355,11 @@ everyModule.performRedirect( function(res, location) {
});

everyModule.moduleTimeout(10000);
everyModule.moduleErrback( function (err, data) {
everyModule.moduleErrback( function (err, seqValues) {
if (! (err instanceof Error)) {
console.log('Warning: Try to pass only Errors');
err = new Error(JSON.stringify(err));
}
data.next(err);
var next = seqValues.next;
next(err);
});
24 changes: 20 additions & 4 deletions lib/modules/facebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,31 @@ oauthModule.submodule('facebook')
fieldsQuery = "?fields=" + this.fields();
}
this.oauth.get(this.apiHost() + '/me' + fieldsQuery, accessToken, function (err, data) {
if (err)
return p.fail(err);
if (err) return p.fail(err);
var oauthUser = JSON.parse(data);
p.fulfill(oauthUser);
})
return p;
})
.convertErr( function (data) {
return new Error(JSON.parse(data.data).error.message);
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var facebookResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
facebookResponse.statusCode
, facebookResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
console.error(err);
throw new Error('Unsupported error type');
}
});

fb.mobile = function (isMobile) {
Expand Down
28 changes: 22 additions & 6 deletions lib/modules/foursquare.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,34 @@ oauthModule.submodule('foursquare')
, queryParams = { oauth_token: accessToken }
request.get({ url: userUrl, qs: queryParams}, function (err, res, body) {
if (err) {
err.extra = {res: res, data: body};
return promise.fail(err);
}
if (res.statusCode !== 200) {
return promise.fail(body);
if (parseInt(res.statusCode/100, 10) !== 2) {
return promise.fail({extra: {data: body, res: res}});
}
var oauthUser = JSON.parse(body).response.user;
return promise.fulfill(oauthUser);
});
return promise;
})

.convertErr( function (data) {
var errMsg = JSON.parse(data.data).meta.errorDetail;
return new Error(errMsg);
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var foursquareResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
foursquareResponse.statusCode
, foursquareResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
console.error(err);
throw new Error('Unsupported error type');
}
});
20 changes: 20 additions & 0 deletions lib/modules/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,24 @@ oauthModule.submodule('github')
p.fulfill(oauthUser);
})
return p;
})
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var ghResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
ghResponse.statusCode
, ghResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
console.error(err);
throw new Error('Unsupported error type');
}
});
49 changes: 40 additions & 9 deletions lib/modules/google.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,20 @@ oauthModule.submodule('google')
.entryPath('/auth/google')
.callbackPath('/auth/google/callback')

.authQueryParam('scope', function () {
return this._scope && this.scope();
.authQueryParam({
access_type: 'offline'
, approval_prompt: 'force'
, scope: function () {
return this._scope && this.scope();
}
})

.addToSession( function (sess, auth) {
this._super(sess, auth);
if (auth.refresh_token) {
sess.auth[this.name].refreshToken = auth.refresh_token;
sess.auth[this.name].expiresInSeconds = parseInt(auth.expires_in, 10);
}
})

.authCallbackDidErr( function (req) {
Expand All @@ -43,19 +55,38 @@ oauthModule.submodule('google')
throw new Error("You must configure handleAuthCallbackError if you are not using express");
}
})
.convertErr( function (data) {
return new Error(data.data.match(/H1>(.+)<\/H1/)[1]);
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var googleResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
googleResponse.statusCode
, googleResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
console.error(err);
throw new Error('Unsupported error type');
}
})

.fetchOAuthUser( function (accessToken) {
var promise = this.Promise()
, userUrl = 'https://www.googleapis.com/oauth2/v1/userinfo'
, queryParams = { oauth_token: accessToken, alt: 'json' };
console.log(queryParams);
request.get({url: userUrl, qs: queryParams}, function (err, res, body) {
, queryParams = { access_token: accessToken, alt: 'json' };
request.get({
url: userUrl
, qs: queryParams
}, function (err, res, body) {
if (err) return promise.fail(err);
if (res.statusCode !== 200) {
return promise.fail(body);
if (parseInt(res.statusCode/100, 10) !== 2) {
return promise.fail({extra: {data: body, res: res}});
}
promise.fulfill(JSON.parse(body));
});
Expand Down
31 changes: 24 additions & 7 deletions lib/modules/linkedin.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,33 @@ oauthModule.submodule('linkedin')

.fetchOAuthUser( function (accessToken, accessTokenSecret, params) {
var promise = this.Promise();
this.oauth.get(this.apiHost() + '/people/~:(id,first-name,last-name,headline,location:(name,country:(code)),industry,num-connections,num-connections-capped,summary,specialties,proposal-comments,associations,honors,interests,positions,publications,patents,languages,skills,certifications,educations,three-current-positions,three-past-positions,num-recommenders,recommendations-received,phone-numbers,im-accounts,twitter-accounts,date-of-birth,main-address,member-url-resources,picture-url,site-standard-profile-request:(url),api-standard-profile-request:(url,headers),public-profile-url)', accessToken, accessTokenSecret, function (err, data) {
if (err) return promise.fail(err);
this.oauth.get(this.apiHost() + '/people/~:(id,first-name,last-name,headline,location:(name,country:(code)),industry,num-connections,num-connections-capped,summary,specialties,proposal-comments,associations,honors,interests,positions,publications,patents,languages,skills,certifications,educations,three-current-positions,three-past-positions,num-recommenders,recommendations-received,phone-numbers,im-accounts,twitter-accounts,date-of-birth,main-address,member-url-resources,picture-url,site-standard-profile-request:(url),api-standard-profile-request:(url,headers),public-profile-url)', accessToken, accessTokenSecret, function (err, data, res) {
if (err) {
err.extra = {data: data, res: res}
return promise.fail(err);
}
var oauthUser = JSON.parse(data);
promise.fulfill(oauthUser);
});
return promise;
})
.convertErr( function (data) {
// var errJson = JSON.parse(data.data)
// , errMsg = errJson.message;
var errMsg = data.data;
return new Error("LinkedIn sent back a " + data.statusCode + " response with data = " + errMsg);
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var linkedInResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
linkedInResponse.statusCode
, linkedInResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
console.error(err);
throw new Error('Unsupported error type');
}
});
9 changes: 3 additions & 6 deletions lib/modules/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ everyModule.submodule('oauth')
var p = this.Promise();
this.oauth.getOAuthRequestToken({ oauth_callback: this._myHostname + this._callbackPath }, function (err, token, tokenSecret, params) {
if (err) {
if (!err.data || -1 == err.data.indexOf('Invalid / expired Token'))
return p.fail(err);
return p.fail(err);
}
p.fulfill(token, tokenSecret);
});
Expand Down Expand Up @@ -163,10 +162,8 @@ everyModule.submodule('oauth')
})
.getAccessToken( function (reqToken, reqTokenSecret, verifier) {
var promise = this.Promise();
this.oauth.getOAuthAccessToken(reqToken, reqTokenSecret, verifier, function (err, accessToken, accessTokenSecret, params) {
if (err && !~(err.data.indexOf('Invalid / expired Token'))) {
return promise.fail(err);
}
this.oauth.getOAuthAccessToken(reqToken + 'kkk', reqTokenSecret, verifier, function (err, accessToken, accessTokenSecret, params) {
if (err) return promise.fail(err);
promise.fulfill(accessToken, accessTokenSecret, params);
});
return promise;
Expand Down
7 changes: 5 additions & 2 deletions lib/modules/oauth2.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,11 @@ everyModule.submodule('oauth2')
}
opts[paramsVia] = params;
request[this._accessTokenHttpMethod](opts, function (err, res, body) {
if (err) return p.fail(err);
if (parseInt(res.statusCode / 100) != 2) return p.fail(body);
if (err) {
err.extra = {data: body, res: res};
return p.fail(err);
}
if (parseInt(res.statusCode / 100) != 2) return p.fail({extra: {res: res, data: body}});
var resType = res.headers['content-type']
, data;
if (resType.substring(0, 10) === 'text/plain') {
Expand Down
28 changes: 22 additions & 6 deletions lib/modules/twitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ oauthModule.submodule('twitter')
.authorizePath('/oauth/authenticate')
.fetchOAuthUser( function (accessToken, accessTokenSecret, params) {
var promise = this.Promise();
this.oauth.get(this.apiHost() + '/users/show.json?user_id=' + params.user_id, accessToken, accessTokenSecret, function (err, data) {
if (err) return promise.fail(err);
this.oauth.get(this.apiHost() + '/users/show.json?user_id=' + params.user_id, accessToken, accessTokenSecret, function (err, data, res) {
if (err) {
err.extra = {data: data, res: res};
return promise.fail(err);
}
var oauthUser = JSON.parse(data);
promise.fulfill(oauthUser);
});
Expand All @@ -31,10 +34,23 @@ oauthModule.submodule('twitter')
throw new Error("You must configure handleAuthCallbackError if you are not using express");
}
})
.convertErr( function (data) {
if (data.data.charAt(0) === '{') { // If we have JSON
return new Error(JSON.parse(data.data).error);
.moduleErrback( function (err, seqValues) {
if (err instanceof Error) {
var next = seqValues.next;
return next(err);
} else if (err.extra) {
var twitterResponse = err.extra.res
, serverResponse = seqValues.res;
serverResponse.writeHead(
twitterResponse.statusCode
, twitterResponse.headers);
serverResponse.end(err.extra.data);
} else if (err.statusCode) {
var serverResponse = seqValues.res;
serverResponse.writeHead(err.statusCode);
serverResponse.end(err.data);
} else {
return new Error(data.data.match(/<error>(.+)<\/error>/)[1]);
console.error(err);
throw new Error('Unsupported error type');
}
});
Loading

0 comments on commit c501bc9

Please sign in to comment.