使用boostrap警报时,angujar摘要错误循环

时间:2016-04-12 10:24:00

标签: javascript angularjs angular-ui-bootstrap

我使用createTextNode和异常处理程序将所有应用程序异常显示为警报。警报具有解除超时设置。

这里的例外处理程序代码(用咖啡写的):

angular-ui-boostrap

和警报定义(用玉写的):

$provide.decorator "$exceptionHandler", ['$delegate', 'alerts', ($delegate, alerts) ->
  (exception, cause) ->
    $delegate(exception, cause)
    if (alerts.elements.length < 5)
      alerts.add('danger', exception.message)
]

问题是如果在摘要周期中出现错误,我会得到一个无限循环。因为每次发生错误时我都会添加一个新警报,以便再次发生摘要循环,从而触发新错误。

当警报被解除,错误被触发,因此添加了新警报等等时也会发生同样的情况。

我该如何解决?是否可以在不触发整个摘要周期的情况下更新警报?但仍然在视图上更新警报。

1 个答案:

答案 0 :(得分:1)

可能没有办法解决这个问题。但你可以做的是覆盖angulars的错误处理程序并在一定时间内计算错误数量并停止应用程序,如果存在由摘要周期引起的某种无限错误循环(普通JS中的所有代码):

function ExceptionService($log,$injector) {

        var errorLog = {};
        var applicationStopped = false;

        /**
         * override method to catch errors
         * @param exception
         * @param cause
         */
        function error(exception, cause) {
            // forward output to console
            $log.error.apply($log, arguments);
            if (!applicationStopped) {
              var cycleBreaked = _digestCycleBreakerCheck();
              if (!cycleBreaked) {
                //not many errors yet, just print to console or do nothing
              } else {
                //p.e. stop the whole angular application by destroying the rootScope
              }
            }
        }

        function _digestCycleBreakerCheck() {
            var cycleBreaked = false;
            if (Object.keys(errorLog).length === 0) {
                _resetErrorLog();
            } else {
                if (errorLog.lastErrorDate >= (_getCurrentTs() - 15)) {
                    errorLog.count += 1;
                    errorLog.lastErrorDate = _getCurrentTs();
                    if (errorLog.count >= 10) {
                        //break digest cycle!
                        cycleBreaked = true;
                    }
                } else {
                    //it has been the first error after more than x seconds
                    _resetErrorLog();
                }
            }
            return cycleBreaked;
        }

        function _resetErrorLog() {
            errorLog.count = 1;
            errorLog.lastErrorDate = _getCurrentTs();
        }

        function _getCurrentTs() {
            return Math.floor(Date.now() / 1000);
        }

        return (error);
    }

请参阅:http://engineering.talis.com/articles/client-side-error-logging/