统一监听Vue、React组件报错

Vue

一、window.onerror

  • 全局监听所有JS报错
  • 但是它是JS级别的,识别不了Vue组件信息
  • 捕捉一些Vue监听不到的错误

在这里插入图片描述

在这里插入图片描述
也可以这么写
在这里插入图片描述

window.onerror
但是,如果用try…catch…捕获的error,无法被window.onerror捕获
在这里插入图片描述

二、errorCaptured生命周期

  • 监听所有下级组件的错误
  • 返回false会阻止向上传播
    在这里插入图片描述
    window.onerror也监听到了(有向上传播)
    在这里插入图片描述
    return false 阻止向上传播: (防止重复捕获)
    在这里插入图片描述
    在这里插入图片描述

三、errorHandler配置

  • Vue全局错误监听,所有组件错误都会汇总到这里
  • 但errorCaptured返回false,不会传播到这里

在这里插入图片描述
在这里插入图片描述
没有return false ,window.onerror也没有执行,errorHandler已经是全局的监听
window.onerror与errorHandler互斥

异步错误

  • 异步回调里的错误, errorHandler监听不到
  • 需要使用window.onerror

在这里插入图片描述
在这里插入图片描述
只有window.onerror监听到了错误

总结

  • errorCaptured监听下级组件的错误,返回false 阻止向上传播
  • errorHandler监听全局Vue组件的错误
  • window.onerror监听其他JS报错,如 异步
    在这里插入图片描述

React

一、ErrorBoundary监听组件渲染报错

监听所有下级组件报错,可降级展示UI(显示 出错啦~~ 友好提示)
只监听组件渲染时的报错,不监听DOM事件、异步错误(可用try-catch、window.onerror)
只在production生产环境生效,测试环境直接抛出错误

src/ErrorBoundary.tsx

import React from 'react'

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      error: null // 存储当前报错信息
    }
  }
  static getDerivedStateFromError(error) {
    // 更新state 时下一次渲染能够显示降级后的UI
    console.log('getDerivedStateFromError...', error)
    return { error }
  }
  componentDidCatch(error, errorInfo) {
    console.info('componentDidCatch...', error, errorInfo)
  }
  render() {
    if (this.state.error) {
      // 提示错误
      return <h1>报错了</h1>
    }
    // 没有错误 正常渲染
    return this.props.children
  }
}

export default ErrorBoundary

index.tsx
在这里插入图片描述

ClassDemo.tsx

import React from 'react'

class ErrorDemo extends React.Component {
  constructor(props:any) {
    super(props)
    this.state = {
        num: 100
    }
  }
  clickHandler = () => {
    // this.state.num() // ErrorBoundary 无法监听DOM事件报错,需要自行 try-catch、window.onerror
  }
  componentDidMount() {
    // throw new Error('mounted error') // ErrorBoundary 可监听渲染过程的报错

    // setTimeout(() => { // 无法监听异步报错,会直接抛出
    //     throw new Error('setTimeout error')
    // }, 1000)
  }
  render() {
    return <div>
      <p>error demo - class</p>
      <button onClick={this.clickHandler}>error</button>
    </div>
  }
}

export default ErrorDemo

FunctionDemo.tsx

import { useState, useEffect } from 'react'

function ErrorDemo() {
    const [num] = useState(100)

    function clickHandler() {
      // num() // ErrorBoundary 无法监听事件报错,需要自行 try-catch
    }

    // useEffect(() => {
    //   throw new Error('mounted error') // ErrorBoundary 可监听渲染过程的报错
    // }, [])

    return <div>
        <p>error demo - functional</p>
        <button onClick={clickHandler}>error</button>
    </div>
}

export default ErrorDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老电影故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值