如何优雅处理前端异常?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何优雅处理前端异常?相关的知识,希望对你有一定的参考价值。

前端一直是距离用户最近的一层,随着产品的日益完善,我们会更加注重用户体验,而前端异常却如鲠在喉,甚是烦人。

一、为什么要处理异常?

异常是不可控的,会影响最终的呈现结果,但是我们有充分的理由去做这样的事情。

  • 增强用户体验;
  • 远程定位问题;
  • 未雨绸缪,及早发现问题;
  • 无法复线问题,尤其是移动端,机型,系统都是问题;
  • 完善的前端方案,前端监控系统;

对于?JS?而言,我们面对的仅仅只是异常,异常的出现不会直接导致?JS?引擎崩溃,最多只会使当前执行的任务终止。

二、需要处理哪些异常?

对于前端来说,我们可做的异常捕获还真不少。总结一下,大概如下:

  • JS?语法错误、代码异常
  • AJAX?请求异常
  • 静态资源加载异常
  • Promise?异常
  • Iframe?异常
  • 跨域 Script error
  • 崩溃和卡顿

下面我会针对每种具体情况来说明如何处理这些异常。

三、Try-Catch 的误区

try-catch?只能捕获到同步的运行时错误,对语法和异步错误却无能为力,捕获不到。

1. 同步运行时错误:

try 
  let name = ‘jartto‘;
  console.log(nam);
 catch(e) 
  console.log(‘捕获到异常:‘,e);

输出:

捕获到异常: ReferenceError: nam is not defined
    at <anonymous>:3:15

2. 不能捕获到语法错误,我们修改一下代码,删掉一个单引号:

try 
  let name = ‘jartto;
  console.log(nam);
 catch(e) 

  console.log(‘捕获到异常:‘,e);

输出:

Uncaught SyntaxError: Invalid or unexpected token

不过语法错误在我们开发阶段就可以看到,应该不会顺利上到线上环境。

3. 异步错误

try 
  setTimeout(() => 
    undefined.map(v => v);
  , 1000)
 catch(e) 
  console.log(‘捕获到异常:‘,e);

我们看看日志:

Uncaught TypeError: Cannot read property ‘map‘ of undefined
    at setTimeout (<anonymous>:3:11)

并没有捕获到异常,这是需要我们特别注意的地方。

四、window.onerror 不是万能的

当?JS?运行时错误发生时,window?会触发一个?ErrorEvent?接口的?error?事件,并执行?window.onerror()

/**
* @param String  message    错误信息
* @param String  source    出错文件
* @param Number  lineno    行号
* @param Number  colno    列号
* @param Object  error  Error对象(对象)
*/

window.onerror = function(message, source, lineno, colno, error) 
   console.log(‘捕获到异常:‘,message, source, lineno, colno, error);

1. 首先试试同步运行时错误

window.onerror = function(message, source, lineno, colno, error) 
// message:错误信息(字符串)。
// source:发生错误的脚本URL(字符串)
// lineno:发生错误的行号(数字)
// colno:发生错误的列号(数字)
// error:Error对象(对象)
console.log(‘捕获到异常:‘,message, source, lineno, colno, error);

Jartto;

可以看到,我们捕获到了异常:

技术图片

2. 再试试语法错误呢?

window.onerror = function(message, source, lineno, colno, error) 
console.log(‘捕获到异常:‘,message, source, lineno, colno, error);

let name = ‘Jartto

控制台打印出了这样的异常:

Uncaught SyntaxError: Invalid or unexpected token

什么,竟然没有捕获到语法错误?

3. 怀着忐忑的心,我们最后来试试异步运行时错误:

window.onerror = function(message, source, lineno, colno, error) 
    console.log(‘捕获到异常:‘,message, source, lineno, colno, error);

setTimeout(() => 
    Jartto;
);

控制台输出了:

以上是关于如何优雅处理前端异常?的主要内容,如果未能解决你的问题,请参考以下文章

如何优雅地查看 JS 错误堆栈?

前端如何优雅处理类数组对象?

如何优雅地处理 Spring Security 中未由 ControllerAdvice 处理的异常?

如何优雅地处理 EF Core 异常

如何优雅地处理Async/Await的异常?

Spring Integration and AMQP:如何优雅地处理反序列化异常?