关于javascript:前端异常示例

4次阅读

共计 3613 个字符,预计需要花费 10 分钟才能阅读完成。

引子

在 前端异样类型及捕捉形式 之后,尝试了本人去封装一下,而后去看了 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
正文完
 0