我正在使用 Angular 1.3.15,我想通过正确处理异常来防止客户端代码进入无限错误循环。
我正在使用Sentry报告异常,但我没有从客户端代码与 Sentry 通信。相反,我将客户端代码的异常报告给 Web API(使用 XHR),然后将其报告给 Sentry。
几天前发生的事情是,有人在 FireFox 10 上访问了我们的网站,因此由于 JavaScript 支持不佳,客户端代码进入了无限错误循环,因此它实际上向我们的 API 发送了垃圾邮件/拒绝服务攻击,但存在异常。我们的 API 落后于 NetScaler,因此我们决定设置一个速率限制器,如果请求达到速率限制器,我们现在返回 503 HTTP 状态代码(服务不可用)。
错误看起来像这样:
([object Object],[object Object],(void 0))@/Static/Scripts/app/vendor/angular-translate/angular-translate.min.js:6 applyDirectivesToNode([object Array],[object HTMLAnchorElement] ,[object Object],(void 0),(void 0),null,[object Array],[object Array],[object Object])@/Static/Scripts/app/vendor/angular/angular.js:7498 compileNodes([object Proxy],(void 0))@/Static/Scripts/app/vendor/angular/angular.js:7040 compileNodes([object Proxy],(void 0))@/Static/Scripts/app/vendor /angular/angular.js:7054 compileNodes([object Proxy],(void 0))@/Static/Scripts/app/vendor/angular/angular.js:7054 compileNodes([object Proxy],(void 0))@ /Static/Scripts/app/vendor/angular/angular.js:7054 compileNodes([object Proxy],(void 0))@/Static/Scripts/app/vendor/angular/angular.js:7054 compileNodes([object Object ],(空白 0),[object Object],(void 0),(void 0),null)@/Static/Scripts/app/vendor/angular/angular.js:7054 ...
现在来解决问题。我想在客户端代码中实现适当的异常处理,因此它会继续向 API/Sentry 报告错误,但如果它收到 HTTP 503 状态代码响应,它应该立即停止脚本执行并暂停。
所以我尝试$exceptionHandler
在我的 Angular 模块配置中实现一个装饰器:
// Flag indicating that the JavaScript execution should be stopped and Sentry should NOT be notified
var stopExecution = false;
$provide.decorator("$exceptionHandler", ['$delegate', function($delegate) {
return function(exception, cause) {
$delegate(exception, cause);
if(stopExecution) return;
// Call Sentry and report the exception
SentryServiceProvider.$get().captureException(exception)
.error(function (data, status, headers, config) {
if(status === 503) {
if(stopExecution) return;
stopExecution = true;
throw new Error('GOT AN 503 ERROR FROM API, STOPPING EXECUTION');
}
});
};
}]);
我captureException()
在 SentryServiceProvider 中的函数只是使用 POST 请求调用 API,并将 JSON 对象中的异常消息和堆栈跟踪作为有效负载发送,并返回一个 $http 承诺。
sentryService.captureException = function (ex) {
return $http.post(API_URL + '/sentry', { Message: ex.message, StackTrace: ex.stack });
};
现在的问题是因为它处于无限循环中,它永远不会进入error()
回调并永远向 API 发送垃圾邮件。我怎么能这样做来防止我的客户端代码中出现无限错误循环,所以当 API 这么说时它会停止?