You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS中$exceptionHandler如何捕获触发错误的HTML元素与函数入参

实现方案

步骤1:给业务函数添加上下文捕获逻辑

你需要的两类信息都可以在函数触发时直接获取:

  • HTML元素可以从事件参数$event.target中读取,包含标签、类型、ID、属性等完整DOM信息
  • 入参可以直接读取函数的传入参数对象
    推荐给需要监控的函数外层包裹try-catch,捕获错误时将上下文信息附加到异常对象后再抛出,示例代码如下:
// 控制器中先注入$location,用于获取当前页面路由
$scope.monitorLength = function($event,item,itemID,mLengths,deny) {
  try {
    // 原有函数逻辑保持不变
    var permitChars = [8,35,36,46] ;  //允许删除、退格键
    var permitZip = [32,109,189] ;  //允许邮编中出现的字符
    var keyCode = $event.keyCode || $event.charCode ;
    if (!permitChars.includes(keyCode)) {
      if (deny == 1 && isNaN(String.fromCharCode(keyCode))) {
        $scope.errMsg = "不允许输入非数字字符,例如+ . , -等" ;
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      } 
      
      if (deny == 2 && (isNaN(String.fromCharCode(keyCode)) || permitZip.includes(keyCode))) {
        $scope.errMsg = "仅允许输入数字、空格和横杠字符" ;
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      } 

      var len = $scope[item][itemID] ;
      if (deny == 1 && (/^0/.test(len) || /^1/.test(len))) {
        $scope.errMsg = "已自动选择国家/区号,请直接输入主号码" ;  
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      } 
      
      var maxLength = parseInt(mLengths[mLengths.length-1]) ;
      if (len && (len.toString().length > maxLength)) {
        $scope.errMsg = "该字段最大长度为" +maxLength+ "个字符"
        $scope.errColor = "red" ;
        $event.preventDefault() ;
        return ;
      }
    } else {
      $scope.errMsg = "" ;
    }
  } catch (e) {
    // 附加自定义上下文信息
    e.bugContext = {
      // 触发元素信息
      triggerElement: $event ? {
        tagName: $event.target.tagName,
        type: $event.target.type,
        id: $event.target.id,
        outerHTML: $event.target.outerHTML
      } : "函数由JS逻辑直接调用,无关联DOM元素",
      // 函数入参
      inputArgs: {
        item: item,
        itemID: itemID,
        mLengths: mLengths,
        deny: deny
      },
      // 可选:当前页面路由信息,用于判断所属页面
      currentRoute: $location.path()
    }
    // 重新抛出异常,让全局错误处理器捕获
    throw e;
  }
}

如果多个函数需要添加该逻辑,可以封装通用的包装函数避免重复代码:

// 通用包装工具
const wrapWithErrorContext = (fn, getContext) => {
  return function() {
    try {
      return fn.apply(this, arguments)
    } catch (e) {
      e.bugContext = getContext.apply(this, arguments)
      throw e
    }
  }
}

// 使用示例
$scope.monitorLength = wrapWithErrorContext(
  // 原函数逻辑
  function($event,item,itemID,mLengths,deny) { /* 原有代码 */ },
  // 上下文获取逻辑
  function($event,item,itemID,mLengths,deny) {
    return {
      triggerElement: $event ? $event.target : null,
      args: Array.from(arguments),
      route: $location.path()
    }
  }
)

步骤2:改造全局$exceptionHandler读取上下文信息

在原有错误处理逻辑中新增对自定义上下文的读取,序列化后添加到邮件内容即可:

.config(function ($provide,apiServiceProvider) {
  $provide.decorator('$exceptionHandler', function($delegate) {
    return function (exception, cause) {
        var msg = `
DateTime: ${new Date()}`;
        msg += `
AppVersion: ${appFullVer}`;
        msg += `
Exception: ${exception.message}`;
        msg += `<br>Stack: ${exception.stack}`;
        // 新增:读取自定义上下文信息
        if (exception.bugContext) {
          msg += `<br>错误上下文:${JSON.stringify(exception.bugContext, null, 2)}`
        }
        if (cause) {
          msg += `<br>Cause: ${cause}`;
        } else {
          msg += `<br>Cause: none passed`;
        }
        if (httpErrorID == 1) {
          msg += `
HTTP Error: ${httpErrorMsg}`;
          httpErrorID = 0;
        }
        if (errTesting == 0) {
          apiServiceProvider.$get().mail(5,"AppError","Bug","App Angular JS Error",msg);
        } else {
          console.log(msg);
        }
      }
  });
})

额外说明

你当前遇到的undefined is not an object (evaluating 'mLengths.length')错误,本质是调用monitorLength时传入的mLengths参数为undefined,添加上下文捕获后你可以直接看到是哪个场景下传参错误,快速定位问题。
如果使用了ui-router,还可以将$state.current.name(当前路由名称)、$state.current.templateUrl(当前模板路径)添加到上下文中,更方便判断错误所属页面。

内容的提问来源于stack exchange,提问作者rolinger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:06:03