最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端异常示例

    正文概述 掘金(XXHolic)   2020-12-02   625

    引子

    在 前端异常类型及捕获方式 之后,尝试了自己去封装一下,然后去看了 sentry 的源码,发现之前的那篇只是一个概括,当采集的时候,需要更加细致的解析,接下来看看各种异常具体是什么样的。

    • Origin
    • My GitHub

    基础知识点

    前端异常一定会接触到 Error 对象,先来简单的了解一下。

    错误的类型:

    • Error : 基类型,其它错误类型都是继承自该类型。
    • EvalError : 使用 eval() 函数而发生异常时抛出。
    • RangeError : 数值超出相应有效范围时的异常。
    • ReferenceError : 访问无效的引用的异常。
    • SyntaxError : 语法错误的异常。
    • TypeError : 变量或参数不是一个有效类型的异常。
    • URIError : encodeURI()decodeURI() 传入无效参数的异常。
    • AggregateError : 一个操作导致多个异常需要报告,例如 Promise.any()
    • InternalError : JavaScript 引擎内部抛出的错误,这个还没有标准化。

    实例共有的标准属性:

    • message : 异常信息。
    • name : 异常名称。

    实例共有的非标准属性:

    • description : 微软的非标准属性,类似 message 。
    • number : 微软的非标准属性,异常数字。
    • fileName : Mozilla 的非标准属性,异常产生所在文件的路径。
    • lineNumber : Mozilla 的非标准属性,异常产生所在文件的行数。
    • columnNumber : Mozilla 的非标准属性,异常产生所在文件的列数。
    • stack : Mozilla 的非标准属性,堆栈跟踪。

    更多异常相关的信息见 ecma-262 Error 和 WebIDL Exceptions 。

    下面看看每种类型的示例。(暂没有考虑框架)

    以下示例环境:

    • Chrome :86.0.4240.198(正式版本) (x86_64)。
    • 使用 nginx 启动了一个本地服务,原生 js 。
    • 为了方便查看更多信息,使用了 try-catch、onerror、onunhandledrejection 。

    EvalError

    EvalError 已不再被 JavaScript 抛出,现在该对象为了保持兼容性存在。用下面的方式可以看到这种异常:

    try {
      throw new EvalError('Hello, EvalError');
    } catch (e) {
      console.log(e instanceof EvalError); // true
      console.log(e.message);              // "Hello, EvalError"
      console.log(e.name);                 // "EvalError"
    }
    

    查一些资料说下面方式就会抛出该类型异常,但试了一下抛出的异常是 TypeError

    new eval();
    

    RangeError

    const arr = new Array(-10)
    

    前端异常示例

    ReferenceError

    let a = undefinedVariable
    

    前端异常示例

    SyntaxError

    eval('hello syntax')
    

    前端异常示例

    有些语法错误是无法捕获的,因为可能导致整个程序无法正常运行,不过这类型大多在编写阶段就会很容易发现。

    const a++;
    

    TypeError

    const a = 'hell';
    a.fun();
    

    前端异常示例

    URIError

    decodeURIComponent('%')
    

    前端异常示例

    AggregateError

    Promise.any([
      Promise.reject(new Error("some error")),
    ]).catch(e => {
      throw e; // 这里抛出,让 onunhandledrejection 接收会有详细的异常信息
    });
    

    前端异常示例

    DOMException

    const node = document.querySelector('#demo'); // 这个要存在
    const refnode = node.nextSibling;
    const newnode = document.createTextNode('异常');
    node.insertBefore(newnode, refnode);
    

    前端异常示例

    DOMError

    已经不推荐使用了,但一些浏览器还是兼容了这个。

    const err = new DOMError('DOMError');
    throw err;
    

    前端异常示例

    ErrorEvent

    const err = new ErrorEvent('ErrorEvent');
    throw err; // onerror 会捕获到
    

    前端异常示例

    资源加载异常

    常见的 linkscriptimg 标签加载异常都是这样类似的信息:

    前端异常示例

    接口请求异常

    基础 XMLHttpRequest 示例:

    const xhr = new XMLHttpRequest();
    xhr.open("GET", "http://localhost:6677/index");
    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4) {
        if (xhr.status == 200) {
          console.info('success')
        } else {
          console.info('xhr error:',xhr)
        }
      }
    };
    xhr.send();
    

    前端异常示例

    基础 fetch 示例:

    fetch("http://localhost:6677/index").then((res) => {
      if (!res.ok) {
        throw res;
      }
    }).catch((e) => {
      console.info('fetch error:',e);
    })
    

    前端异常示例

    Script error.

    这个本地(浏览器直接文件路径访问)很容易出现,例如点击按钮的时候,抛出了一个异常,onerror 也捕获到了,但什么信息也没有:

    前端异常示例

    换成 try-catch 捕获,有了一些信息:

    前端异常示例

    这个应该是一个对象,用对象的形式打印一下:

    前端异常示例

    这样就可以拿到相关的信息进行解析了,可参考 TraceKit 。

    区分

    看到上面的示例,有好几种形式的异常,进行处理的时候,区分判断的依据是什么?

    思路 1

    比较简单的做法,就是不用区分,既然都是异常,整个全都上报,在后台人工查看一样可以达到异常分析排查的目的。

    思路 2

    通过检查特定字段,或者字段的组合来判断区分。针对特定的异常可以做到,所有的就不太清楚了。

    思路 3

    在看 sentry 源码的时候,发现了另外一种思路:根据异常的类型来区分

    使用的主要方法是:

    function getType(value) {
      return Object.prototype.toString.call(value);
    }
    

    按照这个思路,异常类型有:

    • [object Error] : 属于这种类型的异常有 RangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
    • [object Exception] : 这个没找到,但 sentry 里面有写。
    • [object DOMException] : 属于这种类型的异常有 DOMException
    • [object DOMError] : 属于这种类型的异常有 DOMError
    • [object ErrorEvent] : 属于这种类型的异常有 ErrorEvent
    • [object PromiseRejectionEvent] : 这个有些特殊,当上面的 AggregateError 在 catch 里面检查类型时属于 [object Error] ,如果 throw 时,在 onunhandledrejection 里面类型变成了 [object PromiseRejectionEvent]

    这里大概的写一下 sentry 的区分逻辑:

    const exception = 'some value';
    let format;
    if (isErrorEvent(exception) && exception.error) {
      format = doSomething1(exception);
      return format;
    }
    
    if (isDOMError(exception) || isDOMException(exception)) {
      format = doSomething2(exception);
      return format;
    }
    
    // isError 包含的类型有 [object Error] [object Exception] [object DOMException] ,以及继承自 Error 对象的自定义对象。
    if (isError(exception)) {
      format = doSomething3(exception);
      return format;
    }
    
    // isPlainObject 检查类型是 [object Object],isEvent检查的是 wat instanceof Event
    if (isPlainObject(exception) || isEvent(exception)) {
      format = doSomething4(exception);
      return format;
    }
    
    format = doSomething5(exception);
    
    return format;
    
    

    参考资料

    • Error mdn

    实物与图案一致,不用参考。

    前端异常示例


    起源地下载网 » 前端异常示例

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元