从 $http.error 事件返回 $q.reject 的问题
Issues returning $q.reject from an $http.error event
我有一个登录页面,它将用户凭据提交给登录控制器。
但是在授权用户之前,我需要 "open" 一个会话并接收一个有效的 sessionID。
然而,我的主要问题是处理下方 this.openUserSession
API 调用的错误事件。也就是说,我在 $http.error()
事件上 returning 一个 $q.reject()
,但它并没有像我预期的那样冒泡堆栈。
流程如下:
1) 用户输入凭据并单击 "Login" 按钮,调用 LoginCtrl
函数 loginUser()
2) 我立即调用 ing userService.initUserSession
以获得有效的 sessionID。
3) 如果成功,则调用loginService.authUser
4)如果无效的sessionID,那么我需要return$q.reject
并显示消息
"Could not open user session"
***** 代码详细信息 *****
请注意,我首先 "init" that.initRzr
中的应用程序,然后我在下面调用 that.openUserSession
:
this.initUserSession = function initSession($rootScope, username) {
var deferred = $q.defer();
deferred.notify("Establishing Session ID...");
$rootScope.userID = username;
var that = this;
this.getRazorInitParams().then(function (razorEnvJson) {
that.initRzr(razorEnvJson).then(function (data) {
if (data.status.match(/SUCCESS/g)) {
// ******** OPEN USER SESSION ***********
that.openUserSession(razorEnvJson).then(function (data) {
// ... some code omitted here.
deferred.resolve(sessionID);
return sessionID;
});
}
}, function (error) {
// *** I NEVER HIT LINE !!! ***
deferred.reject('Could not open user session.');
});
});
return deferred.promise;
}
**** 打开用户会话 ***
注意:我在这里输入 .error()
代码,因为我可以看到控制台记录的消息 "Cannot open a user session via api cal..."。但是,处理似乎就此停止,我的登录屏幕只是冻结并显示微调器图标。
this.openUserSession = function (razorEnvParams) {
// init some variables here...
var url = "http://" + _domain + ":" + _port + controllerpath + "?userid=" + user + "&pass=" + pass;
var deferred = $q.defer();
deferred.notify("Opening user session...");
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true',
'Content-Type': 'application/json'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
console.log("Cannot open a user session via api call. Errors details: " + data);
deferred.reject("Could not open a user session.");
});
return deferred.promise;
}
如果不清楚,我会尽力改进post。请指教...
提前致谢。
鲍勃
**** 更新 ****
根据下面 JB Nizet 的回答,我错过了 that.openUserSession
的错误回调。我在下面添加了 function(error)
,它按预期工作。
我现在将继续 JB posted 的链接建议。
this.initUserSession = function initSession($rootScope, username) { // ESTABLISH A RAGE CONNECTION AND SESSION ID !
var deferred = $q.defer();
deferred.notify("Establishing Rage Session ID...");
var that = this;
this.getRazorInitParams().then(function (razorEnvJson) {
that.initRazor(razorEnvJson).then(function (data) {
if (data.status.match(/SUCCESS/g)) {
that.openUserSession(razorEnvJson).then(function (data) {
deferred.resolve(sessionID);
return sessionID;
}, function (error) {
deferred.reject('Could not open user session.');
});
}
}, function (error) { // **** ADDED ERROR HANDLING ***
deferred.reject('Could not initial a user session.');
});
});
return deferred.promise;
}
openUserSession()
失败,并且您没有针对该失败的任何错误回调,因此承诺永远不会被解决或拒绝。
此错误和大的叠瓦是由您使用 promise antipattern 引起的。改为使用链接:
that.getRazorInitParams()
.then(that.initRzr)
.then(that.openUserSession)
.catch(function() { ... });
无需创建延迟和解析它。只需使用链接。例如,openUserSession()
可以替换为
this.openUserSession = function (razorEnvParams) {
var url = "http://" + _domain + ":" + _port + controllerpath;
return $http({
method: 'POST',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true',
'Content-Type': 'application/json'
},
withCredentials: true,
url: url,
params: {
userid: user,
pass: pass
}
}).then(function (response) {
return response.data;
});
}
此外,永远不要使用 GET 来传输秘密凭据:它们最终会以纯文本形式出现在各种日志中。永远不要连接参数。它们必须经过编码,Angular 通过使用 params
.
为您完成编码
我有一个登录页面,它将用户凭据提交给登录控制器。 但是在授权用户之前,我需要 "open" 一个会话并接收一个有效的 sessionID。
然而,我的主要问题是处理下方 this.openUserSession
API 调用的错误事件。也就是说,我在 $http.error()
事件上 returning 一个 $q.reject()
,但它并没有像我预期的那样冒泡堆栈。
流程如下:
1) 用户输入凭据并单击 "Login" 按钮,调用 LoginCtrl
函数 loginUser()
2) 我立即调用 ing userService.initUserSession
以获得有效的 sessionID。
3) 如果成功,则调用loginService.authUser
4)如果无效的sessionID,那么我需要return$q.reject
并显示消息
"Could not open user session"
***** 代码详细信息 *****
请注意,我首先 "init" that.initRzr
中的应用程序,然后我在下面调用 that.openUserSession
:
this.initUserSession = function initSession($rootScope, username) {
var deferred = $q.defer();
deferred.notify("Establishing Session ID...");
$rootScope.userID = username;
var that = this;
this.getRazorInitParams().then(function (razorEnvJson) {
that.initRzr(razorEnvJson).then(function (data) {
if (data.status.match(/SUCCESS/g)) {
// ******** OPEN USER SESSION ***********
that.openUserSession(razorEnvJson).then(function (data) {
// ... some code omitted here.
deferred.resolve(sessionID);
return sessionID;
});
}
}, function (error) {
// *** I NEVER HIT LINE !!! ***
deferred.reject('Could not open user session.');
});
});
return deferred.promise;
}
**** 打开用户会话 ***
注意:我在这里输入 .error()
代码,因为我可以看到控制台记录的消息 "Cannot open a user session via api cal..."。但是,处理似乎就此停止,我的登录屏幕只是冻结并显示微调器图标。
this.openUserSession = function (razorEnvParams) {
// init some variables here...
var url = "http://" + _domain + ":" + _port + controllerpath + "?userid=" + user + "&pass=" + pass;
var deferred = $q.defer();
deferred.notify("Opening user session...");
$http({
method: 'GET',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true',
'Content-Type': 'application/json'
},
withCredentials: true,
url: url
}).success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
console.log("Cannot open a user session via api call. Errors details: " + data);
deferred.reject("Could not open a user session.");
});
return deferred.promise;
}
如果不清楚,我会尽力改进post。请指教...
提前致谢。
鲍勃
**** 更新 ****
根据下面 JB Nizet 的回答,我错过了 that.openUserSession
的错误回调。我在下面添加了 function(error)
,它按预期工作。
我现在将继续 JB posted 的链接建议。
this.initUserSession = function initSession($rootScope, username) { // ESTABLISH A RAGE CONNECTION AND SESSION ID !
var deferred = $q.defer();
deferred.notify("Establishing Rage Session ID...");
var that = this;
this.getRazorInitParams().then(function (razorEnvJson) {
that.initRazor(razorEnvJson).then(function (data) {
if (data.status.match(/SUCCESS/g)) {
that.openUserSession(razorEnvJson).then(function (data) {
deferred.resolve(sessionID);
return sessionID;
}, function (error) {
deferred.reject('Could not open user session.');
});
}
}, function (error) { // **** ADDED ERROR HANDLING ***
deferred.reject('Could not initial a user session.');
});
});
return deferred.promise;
}
openUserSession()
失败,并且您没有针对该失败的任何错误回调,因此承诺永远不会被解决或拒绝。
此错误和大的叠瓦是由您使用 promise antipattern 引起的。改为使用链接:
that.getRazorInitParams()
.then(that.initRzr)
.then(that.openUserSession)
.catch(function() { ... });
无需创建延迟和解析它。只需使用链接。例如,openUserSession()
可以替换为
this.openUserSession = function (razorEnvParams) {
var url = "http://" + _domain + ":" + _port + controllerpath;
return $http({
method: 'POST',
encoding: 'JSON',
headers: {
'Access-Control-Allow-Origin': 'true',
'Content-Type': 'application/json'
},
withCredentials: true,
url: url,
params: {
userid: user,
pass: pass
}
}).then(function (response) {
return response.data;
});
}
此外,永远不要使用 GET 来传输秘密凭据:它们最终会以纯文本形式出现在各种日志中。永远不要连接参数。它们必须经过编码,Angular 通过使用 params
.