从$ http.error事件

时间:2015-12-21 16:50:51

标签: angularjs angular-promise

我有一个登录页面,用于向登录控制器提交用户凭据。 但在授权用户之前,我需要打开"打开"会话并接收有效的会话ID。

我的主要问题是在下面的this.openUserSession API 调用中处理错误事件。也就是说,我在$q.reject()事件中返回了$http.error(),但它并没有像我预期的那样在堆栈中冒泡。

以下是流程:

1)用户输入凭据并单击"登录"按钮,调用LoginCtrl函数loginUser()

2)我立即打电话给userService.initUserSession以获得有效的会话ID。

3)如果成功,请致电loginService.authUser 4)如果sessionID无效,那么我需要返回$q.reject并显示消息 "无法打开用户会话"

*****代码详情*****

请注意,首先是我" 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;
}




**** OPEN USER SESSION ***

注意:我在这里点击.error()代码,因为我可以看到控制台记录的消息"无法通过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;
}




如果不清楚,我会尝试改进这篇文章。请指教......

提前感谢。

鲍勃

****更新****

根据JB Nizet的回答,我错过了that.openUserSession的错误回调。我在下面添加了function(error),它按预期工作。

我现在将继续讨论JB发布的链接建议。



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;
}




1 个答案:

答案 0 :(得分:2)

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为您执行此操作。