@@ -20,52 +20,82 @@ function makeOpts(url, expectedStatus) {
2020 opts . url = url ;
2121 opts . headers = { } ;
2222 opts . expectedStatus = expectedStatus || 200 ;
23+ opts . retry = 0 ;
2324
2425 var core = require ( './core' ) ;
2526 if ( core . isLogin ( ) ) signOpts ( opts , core . getUser ( ) ) ;
2627 return opts ;
2728}
2829
29- function checkError ( e , resp , expectedStatus , msg ) {
30- if ( e ) return e ;
30+ var EXPIRED_ERROR = {
31+ msg : 'session expired, please login again' ,
32+ statusCode : - 1
33+ } ;
3134
32- var code = resp . statusCode ;
33- if ( resp && code !== expectedStatus ) {
35+ function checkError ( e , resp , expectedStatus , msg ) {
36+ if ( ! e && resp && resp . statusCode !== expectedStatus ) {
37+ var code = resp . statusCode ;
3438 if ( code === 403 || code === 401 ) {
35- msg = msg || 'session expired, please login again' ;
39+ e = EXPIRED_ERROR ;
40+ log . debug ( 'session expired:' + code ) ;
41+ } else {
42+ e = { msg : msg || 'http error' , statusCode : code } ;
3643 }
37- e = { msg : msg || 'http error' , statusCode : code } ;
3844 }
3945 return e ;
4046}
4147
48+ function relogin ( opts , cb ) {
49+ log . debug ( 'session expired, try to re-login...' ) ;
50+ ++ opts . retry ;
51+
52+ var core = require ( './core' ) ;
53+ var user = core . getUser ( ) ;
54+ if ( ! user ) {
55+ log . debug ( 'login failed: no user found, please login again' ) ;
56+ return cb ( ) ;
57+ }
58+
59+ core . login ( user , function ( e , user ) {
60+ if ( e ) {
61+ log . debug ( 'login failed:' + e ) ;
62+ } else {
63+ log . debug ( 'login successfully, cont\'d...' ) ;
64+ signOpts ( opts , user ) ;
65+ }
66+ // for now we don't care result, just blindly retry
67+ return cb ( ) ;
68+ } ) ;
69+ }
70+
4271// leetcode.com is limiting one session alive in the same time,
4372// which means once you login on web, your cli session will get
4473// expired immediately. In that case we will try to re-login in
4574// the backend to give a seamless user experience.
4675function requestWithReLogin ( opts , cb ) {
76+ if ( opts . retry > 1 ) return cb ( EXPIRED_ERROR ) ;
77+
4778 var req = request ( opts , function ( e , resp , body ) {
4879 e = checkError ( e , resp , opts . expectedStatus ) ;
4980
50- // not session expired: transparently pass down
51- if ( ! config . AUTO_LOGIN || ! e ) return cb ( e , resp , body , req ) ;
52- if ( e . statusCode !== 403 && e . statusCode !== 401 ) return cb ( e , resp , body , req ) ;
53-
54- log . debug ( 'session expired, auto re-login...' ) ;
55-
56- var core = require ( './core' ) ;
57- var user = core . getUser ( ) ;
58- core . login ( user , function ( e2 , user ) {
59- if ( e2 ) return cb ( e , resp , body , req ) ;
60-
61- log . debug ( 'login successfully, cont\'d...' ) ;
62- signOpts ( opts , user ) ;
63-
64- req = request ( opts , function ( e , resp , body ) {
65- e = checkError ( e , resp , opts . expectedStatus ) ;
66- return cb ( e , resp , body , req ) ;
81+ if ( e === EXPIRED_ERROR && config . AUTO_LOGIN ) {
82+ relogin ( opts , function ( ) {
83+ requestWithReLogin ( opts , cb ) ;
6784 } ) ;
68- } ) ;
85+ return ;
86+ }
87+
88+ try {
89+ return cb ( e , resp , body , req ) ;
90+ } catch ( e2 ) {
91+ if ( e2 === EXPIRED_ERROR && config . AUTO_LOGIN ) {
92+ relogin ( opts , function ( ) {
93+ requestWithReLogin ( opts , cb ) ;
94+ } ) ;
95+ return ;
96+ }
97+ return cb ( e2 ) ;
98+ }
6999 } ) ;
70100}
71101
@@ -81,8 +111,10 @@ leetcodeClient.getProblems = function(cb) {
81111
82112 // leetcode permits anonymous access to the problem list
83113 // while we require login first to make a better experience.
84- if ( json . user_name . length === 0 )
85- return cb ( 'session expired, please login again' ) ;
114+ if ( json . user_name . length === 0 ) {
115+ log . debug ( 'no user info in list response, maybe session expired...' ) ;
116+ throw EXPIRED_ERROR ;
117+ }
86118
87119 var problems = json . stat_status_pairs
88120 . filter ( function ( p ) {
0 commit comments