如何搞定前端异常监控?

webfunny前端监控
异常是指用户在使用应用时无法得到预期结果,处理异常的重要性以及前端中的异常类型和捕获方法。其中,try-catch只能捕获同步运行错误,而无法捕获语法和异步错误。另外,异常的上报也是需要考虑的问题,例如调整发送频率和设置采集率等。

什么是异常

用户在使用应用时,可能会遇到预期之外的结果。不同的异常情况带来的后果也会有所不同,有些可能只会让用户感到不满意,而有些则可能导致产品无法正常使用,从而使用户失去对产品的信任。

为什么要处理异常

  • 增强用户体验
  • 远程定位问题
  • 无法复现问题,特别是移动端,各种原因,可能是系统版本,机型等等

前端有哪些异常

在这里插入图片描述

如何捕获异常

try-catch
try-catch 只能捕获同步运行错误,对语法和异步错误却捕获不到。
1、同步运行错误

try {
    kill;
} catch(err) {
    console.error('try: ', err);
}

结果:try: ReferenceError: kill is not defined
2、无法捕获语法错误

try {
    let name = '1;
} catch(err) {
    console.error('try: ', err);
}

结果:Unterminated string constant
编译器能够阻止运行语法错误。
3、无法捕获异步错误

try {
    setTimeout(() => {
        undefined.map(v => v);
    }, 1000);
} catch(err) {
    console.error('try: ', err);
}

在此代码中,出现了一个未捕获的类型错误。无法读取未定义的属性’map’。
window.onerror
当JavaScript在运行时发生错误(包括语法错误),window会引发一个error事件,该事件接口属于ErrorEvent。同时,window.onerror()函数将被执行。如果该函数返回true,则会阻止默认的事件处理函数执行。
1、同步运行错误

/**
* @param {String}  message   错误信息
* @param {String}  source    出错文件
* @param {Number}  lineno    行号
* @param {Number}  colno     列号
* @param {Object}  error     error对象
*/
window.onerror = (message, source, lineno, colno, error) => {
    console.error('捕获异常:', message, source, lineno, colno, error);
    return true;
};

kill;

结果:捕获异常: Uncaught ReferenceError: kill is not defined
2、无法捕获语法错误

/**
* @param {String}  message   错误信息
* @param {String}  source    出错文件
* @param {Number}  lineno    行号
* @param {Number}  colno     列号
* @param {Object}  error     error对象
*/
window.onerror = (message, source, lineno, colno, error) => {
    console.error('捕获异常:', message, source, lineno, colno, error);
    return true;
};

let name = '1;

结果:Unterminated string constant
编译器能够阻止运行语法错误。
3、异步错误

/**
* @param {String}  message   错误信息
* @param {String}  source    出错文件
* @param {Number}  lineno    行号
* @param {Number}  colno     列号
* @param {Object}  error     error对象
*/
window.onerror = (message, source, lineno, colno, error) => {
    console.error('捕获异常:', message, source, lineno, colno, error);
    return true;
};

setTimeout(() => {
    undefined.map(v => v);
}, 1000);

在SEO运营中,捕获到异常信息:未捕获的类型错误:无法读取未定义的属性’map’。
window.addEventListener(‘error’)
当加载资源(例如或

<script>
window.addEventListener('error', (err) => {
    console.error('捕获异常:', err);
}, true);
</script>
<img src="./test.jpg" />

我们可以使用符合SEO规则的方式重新表达这段文字: “我们检测到一次异常捕获事件:“错误事件”{isTrusted: true, type: “error”, target: img, currentTarget: Window, eventPhase: 1, …}”
window.addEventListener(‘unhandledrejection’)
当Promise被拒绝且没有拒绝处理器时,会触发未处理的拒绝事件(unhandledrejection);这种情况可能发生在window环境下,也可能发生在Worker环境中。这对于调试退回错误处理非常有帮助,并符合SEO规则。

window.addEventListener("unhandledrejection", (err) => {
    err.preventDefault();
    console.error('捕获异常:', err);
});

Promise.reject('promise');

在符合SEO规则的情况下,重写以下文本:捕获到一个异常,异常信息是:PromiseRejectionEvent {isTrusted: true, promise: Promise, reason: “promise”, type: “unhandledrejection”, target: Window, …}
Vue

Vue.config.errorHandler = (err, vm, info) => {
  console.error('捕获异常:', err, vm, info);
}

React
React 16强化了错误处理功能,新增了一个名为componentDidCatch的内置函数,能够方便地捕获React产生的错误信息。

componentDidCatch(error, info) {
    console.error('捕获异常:', error, info);
}

但是,推荐ErrorBoundary
为了遵守SEO规则,用户界面中的JavaScript错误不应该对整个应用程序造成破坏。为了解决React用户在面对此问题时的困扰,React 16引入了一个新的概念,即“错误边界”。
新建ErrorBoundary.jsx组件:

import React from 'react';
import { Result, Button } from 'antd';

class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false, info: '' };
    }
  
    static getDerivedStateFromError(error) {
        return { hasError: true };
    }

    componentDidCatch(error, info) {
        this.setState({
            info: error + ''
        });
    }
  
    render() {
        if (this.state.hasError) {
            // 你可以渲染任何自定义的降级 UI
            return (
                <Result
                    status="500"
                    title="500"
                    subTitle={this.state.info}
                    extra={<Button type="primary">Report feedback</Button>}
                />
            );
        }
  
        return this.props.children; 
    }
}

export default ErrorBoundary;

使用:

<ErrorBoundary>
    <App />
</ErrorBoundary>

注意

  • 错误边界不会捕获以下方面的错误
  • 事件处理程序
  • 异步代码(例如setTimeout或requestAnimationFrame回调)
  • 服务器端渲染
  • 在错误边界本身(而不是其子级)中引发的错误

iframe
由于浏览器的"同源策略"限制,处理iframe异常不太容易,除了基本属性如宽度和高度,无法从iFrame中获取太多信息。

Sentry
业界非常优秀的一款监控异常的产品,作者也是用的这款,文档齐全。
需要上报哪些信息
错误id
用户id
用户名
用户IP
设备
错误信息
游览器
系统版本
应用版本
机型
时间戳
异常级别(error、warning、info)
异常上报
1、Ajax发送数据
2、动态创建img标签
如果服务器负载过高,可能是因为异常数据量过大。为了解决这个问题,可以考虑将异常信息存储在客户端,并设定时间阀值,当达到阀值时进行上报。另外,可以调整采集率来减少数据量。采集率的设定应该根据实际情况来进行,可以使用随机数或某些用户特征来选择合适的采集率。

参考文档:webfunny前端监控异常如何做


以上是<如何做前端监控异常>操作分享, PS: 如果你是前端工程师同学,欢迎试用体验【webfunny前端监控系统】
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值