简体   繁体   中英

angularjs capture html element and data that triggered an $exceptionHandler error?

My app has a working $exceptionHandler , if an angularJS error occurs, it captures the error and emails the data back to me. But its not capturing the HTML element that triggered the $scope function nor is it capturing the data that was passed to the function that caused the error to trigger.

To elaborate, I have multiple pages within my app that use that use the same controller which in turn are using the same functions. As an example, the same validation monitorLength function is used on multiple pages where the user is inputting data, in some cases its on an <input type='tel' ng-keydown="monitorLength($event,this.id,phoneLength,1)"> field, in other cases on a <input type='number' ng-keydown="monitorLength($event,this.id,postalLength,2)"> field and in some cases the function is being called by another function.

But when the error/exception is thrown, all it tells me is something like the following making it almost impossible to determine which page/template/input field the function was used on or what the data was that caused the function to error:

Exception: undefined is not an object (evaluating 'mLengths.length')
Stack: ionic://localhost/js/controllers.js:1291:47

In the error handling, how can I also get A) what HTML input/button/field that called the function AND B) get the data that was passed to the function that caused it to error?

Using the example mentioned, here is the monitorLength function:

  var permitChars = [8,35,36,46] ;  //allow delete and backspace
  var permitZip = [32,109,189] ;  //allow characters in zip code
  $scope.monitorLength = function($event,item,itemID,mLengths,deny) {
    //deny = 1 = phone
    //       2 = zip
    var keyCode = $event.keyCode || $event.charCode ;
    if (!permitChars.includes(keyCode)) {
      if (deny == 1 && isNaN(String.fromCharCode(keyCode))) {
        $scope.errMsg = "Non-numeric characters are not permitted.  IE: + . , - etc" ;
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      } 
      
      if (deny == 2 && (isNaN(String.fromCharCode(keyCode)) || permitZip.includes(keyCode))) {
        $scope.errMsg = "Only numbers, space and dash/minus characters are permitted" ;
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      } 

      var len = $scope[item][itemID] ;
      if (deny == 1 && (/^0/.test(len) || /^1/.test(len))) {
        $scope.errMsg = "Country/Prefix code already selected, just enter main phone number" ;  
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      } 
      
      var maxLength = parseInt(mLengths[mLengths.length-1]) ;
      if (len && (len.toString().length > maxLength)) {
        $scope.errMsg = "Max length is " +maxLength+ " chars for this field"
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      }
    } else {
      $scope.errMsg = "" ;
    }
  }

And here is my error/exceptionHandler:

.config(function ($provide,apiServiceProvider) {
  $provide.decorator('$exceptionHandler', function($delegate) {
    return function (exception, cause) {
        // return emailApi(eType,cat,topic,subject,msg) ;
        var msg = "\nDateTime: " + new Date() ;
        msg = msg+ "\nAppVersion: " +appFullVer ;
        msg = msg + "\nException: " +exception.message ;
        msg = msg + "\n<br>Stack: " +exception.stack ;
        if (cause) {
          msg = msg + "\n<br>Cause: " +cause ;
        } else {
          msg = msg + "\n<br>Cause: none passed" ;
        }
        if (httpErrorID == 1) {
          msg = msg+ "\nHTTP Error: " +httpErrorMsg ;
          httpErrorID = 0 ;
        }
        if (errTesting == 0) {
          apiServiceProvider.$get().mail(5,"AppError","Bug","App Angular JS Error",msg) ;
        } else {
          console.log(msg) ;
        }
      }
  }) ;
})

Is mLengths ever undefined , etc?

Does setting a value for mLengths change anything?

$scope.mLengths = mLengths || [];

Also, refactoring like so

const index = mLengths.length - 1;
parseInt(mLengths[index])

could be useful in debugging.

I don't expect my code to work, only to express ideas.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM