Restangular - 如何覆盖错误拦截器
Restangular - How to override Error Interceptors
我正在使用 AngularJS v1.2.16 和 Restangular v1.4.0,想知道是否可行覆盖 ErrorInterceptor。如果是,如何?如果不是,我该如何解决?
我配置了这样的错误拦截器:
RestangularProvider.setErrorInterceptor(
function ( response ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
$location.path("/login");
});
}
else {
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// Stop the promise chain.
return false;
}
);
然后,在另一个地方,我进行了一个带有错误处理的 POST 调用。
function saveApple( apple ) {
Restangular.all("apple/save").post( apple ).then(
function ( response ) {
console.log("Saved");
},
function ( response ) {
// This is not being called.
console.log("Error with status code", response.status);
}
);
}
我明白,我的 "second" 错误处理程序没有被调用,因为我在 ErrorInterceptor
上 returning false
。
但是我该如何解决这个问题呢?我的应用程序中有很多 "REST operations",但只有少数几个,我想要在出现问题时自定义行为。
到目前为止,我想到的唯一解决方法是制作 ErrorInterceptor
return true
,对于所有其他 REST 操作,我复制粘贴相同的错误处理程序(一个更通用的)。但这是我最不想做的事。
现在,是这样流动的:
- 错误拦截器 > 结束。
如果可能的话,我希望它是这样的:(仅针对特定方法 - 并非全部)。
- ErrorInterceptor > Especific_ErrorHandler(如果存在)> End.
也可以这样:
- Especific_ErrorHandler(如果存在)> ErrorInterceptor > End.
两种方式都适合我。
参考文献:
https://github.com/mgonto/restangular#seterrorinterceptor
https://github.com/mgonto/restangular#how-can-i-handle-errors
提前致谢!
是的,您可以创建自定义 httpErrorHandler
。
- 首先你需要创建一个
.factory
,我们称它为httpErrorHandler
.factory('httpErrorHandler', function ($rootScope) {
return {
'error': function (rejection) {
if (rejection.status === 422) {
$rootScope.$broadcast('422_error', rejection.data);
} else if (rejection.status === 403) {
$rootScope.$broadcast('403_error', rejection.data);
} else {
$rootScope.$broadcast('unknown', rejection.data);
}
return $q.reject(rejection);
}
};
}
- 然后将该工厂注册到
$httpProvider
拦截器
.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpErrorHandler');
});
然后只需在应用程序中的任何位置捕获 $rootScope
事件并处理它们,或者在拦截器中添加一些逻辑。
我希望这会按预期工作。
这是您的代码:
RestangularProvider.setErrorInterceptor(
function ( response ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
$location.path("/login");
});
}
else {
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// Stop the promise chain.
return false;
}
);
为什么要使用拦截器?
- 因为您需要全面的对话框来显示错误消息。
停止承诺链,这是不好的做法吗?
我不知道。许多人使用错误回调;错误回调的一个用例是进行一些清理。如果你杀死承诺链,你如何确保清理完成?停止承诺链意味着您的错误回调、您的 catch
块和您的 finally
块将不会被调用。
在文档中,清理已经完成,你可以看到 deferred.reject
被传递了。
https://github.com/mgonto/restangular#seterrorinterceptor
也许您误解了文档中的示例。
可能的解决方案#1
// DON'T stop the promise chain.
return true;
可能的解决方案#2
不要在错误拦截器中处理未知错误。
RestangularProvider.setErrorInterceptor(
function ( response ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
$location.path("/login");
});
// Stop the promise chain.
// all unauthorized access are handled the same.
return false;
}
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// DON'T stop promise chain since error is not handled
return true;
}
);
可能的解决方案#3
停止承诺链时调用 reject
。
RestangularProvider.setErrorInterceptor(
function ( response, deferred, responseHandler ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
// continue promise chain in this callback.
deferred.reject("unauthorized");
$location.path("/login");
});
// Stop the promise chain here
// all unauthorized access are handled the same.
return false;
}
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// DON'T stop promise chain since error is not handled
return true;
}
);
我正在使用 AngularJS v1.2.16 和 Restangular v1.4.0,想知道是否可行覆盖 ErrorInterceptor。如果是,如何?如果不是,我该如何解决?
我配置了这样的错误拦截器:
RestangularProvider.setErrorInterceptor(
function ( response ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
$location.path("/login");
});
}
else {
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// Stop the promise chain.
return false;
}
);
然后,在另一个地方,我进行了一个带有错误处理的 POST 调用。
function saveApple( apple ) {
Restangular.all("apple/save").post( apple ).then(
function ( response ) {
console.log("Saved");
},
function ( response ) {
// This is not being called.
console.log("Error with status code", response.status);
}
);
}
我明白,我的 "second" 错误处理程序没有被调用,因为我在 ErrorInterceptor
上 returning false
。
但是我该如何解决这个问题呢?我的应用程序中有很多 "REST operations",但只有少数几个,我想要在出现问题时自定义行为。
到目前为止,我想到的唯一解决方法是制作 ErrorInterceptor
return true
,对于所有其他 REST 操作,我复制粘贴相同的错误处理程序(一个更通用的)。但这是我最不想做的事。
现在,是这样流动的:
- 错误拦截器 > 结束。
如果可能的话,我希望它是这样的:(仅针对特定方法 - 并非全部)。
- ErrorInterceptor > Especific_ErrorHandler(如果存在)> End.
也可以这样:
- Especific_ErrorHandler(如果存在)> ErrorInterceptor > End.
两种方式都适合我。
参考文献:
https://github.com/mgonto/restangular#seterrorinterceptor https://github.com/mgonto/restangular#how-can-i-handle-errors
提前致谢!
是的,您可以创建自定义 httpErrorHandler
。
- 首先你需要创建一个
.factory
,我们称它为httpErrorHandler
.factory('httpErrorHandler', function ($rootScope) {
return {
'error': function (rejection) {
if (rejection.status === 422) {
$rootScope.$broadcast('422_error', rejection.data);
} else if (rejection.status === 403) {
$rootScope.$broadcast('403_error', rejection.data);
} else {
$rootScope.$broadcast('unknown', rejection.data);
}
return $q.reject(rejection);
}
};
}
- 然后将该工厂注册到
$httpProvider
拦截器
.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpErrorHandler');
});
然后只需在应用程序中的任何位置捕获 $rootScope
事件并处理它们,或者在拦截器中添加一些逻辑。
我希望这会按预期工作。
这是您的代码:
RestangularProvider.setErrorInterceptor(
function ( response ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
$location.path("/login");
});
}
else {
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// Stop the promise chain.
return false;
}
);
为什么要使用拦截器? - 因为您需要全面的对话框来显示错误消息。
停止承诺链,这是不好的做法吗?
我不知道。许多人使用错误回调;错误回调的一个用例是进行一些清理。如果你杀死承诺链,你如何确保清理完成?停止承诺链意味着您的错误回调、您的 catch
块和您的 finally
块将不会被调用。
在文档中,清理已经完成,你可以看到 deferred.reject
被传递了。
https://github.com/mgonto/restangular#seterrorinterceptor
也许您误解了文档中的示例。
可能的解决方案#1
// DON'T stop the promise chain.
return true;
可能的解决方案#2
不要在错误拦截器中处理未知错误。
RestangularProvider.setErrorInterceptor(
function ( response ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
$location.path("/login");
});
// Stop the promise chain.
// all unauthorized access are handled the same.
return false;
}
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// DON'T stop promise chain since error is not handled
return true;
}
);
可能的解决方案#3
停止承诺链时调用 reject
。
RestangularProvider.setErrorInterceptor(
function ( response, deferred, responseHandler ) {
if ( response.status == 401 ) {
dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
.result.then( function () {
// continue promise chain in this callback.
deferred.reject("unauthorized");
$location.path("/login");
});
// Stop the promise chain here
// all unauthorized access are handled the same.
return false;
}
// Some other unknown Error.
console.log( response );
dialogs.error(response.statusText + " - Error " + response.status,
"An unknown error has occurred.<br>Details: " + response.data);
}
// DON'T stop promise chain since error is not handled
return true;
}
);