前端常见异常及如何捕获

全局捕获-架构侧

  1. js全局异常捕获:window.onEerror 和 window.addEventLisenter('error')

  2. Promise全局异常捕获:unhandledrejection

  3. 框架级的全局异常捕获

    1. React:React的ErrorBoundary
    scala 复制代码
    // ErrorBoundary的示例
    class ErrorBoundary extends React.Component {
        constructor(props) {
          super(props);
          this.state = { hasError: false };
        }
      
        componentDidCatch(error, info) {
          this.setState({ hasError: true });
          // 在这里可以做异常的上报
          logErrorToMyService(error, info);
        }
      
        render() {
          if (this.state.hasError) {
            return <h1>Something went wrong.</h1>;
          }
          return this.props.children;
      }
      
      <ErrorBoundary>
        <MyWidget />
      </ErrorBoundary>
    1. Vue:Vue的Vue.config.errorHandler
    2. axios: 请求统一底层封装异常处理拦截器 interceptors

全局捕获-框架层

  1. Vue 用 errorHandler 和 React 用 componentDidCatch

局部捕获-业务侧

可疑代码块try-catch

try catch能捕获捉到运行时非异步错误,无法捕获语法错误和异步错误。这个需要注意。

合理使用,不要过度使用。有得异常需要抛出去给外部处理。

常见的需要注意用try-catch包裹,捕获异常的情况

  1. JSON处理必须使用try catch捕获异常
javascript 复制代码
try {
  const res=fetch(*)
  JSON.parse(res); // res 为服务端返回的数据
} catch(e) {
   // 捕获到详细的错误,在这里处理日志上报或其他异常处理等逻辑,如是否提示用户,是否有异常下的兜底数据,比如使用缓存数据等
  console.error("服务端数据格式返回异常,无法解析", res);
  
}

// 注意:下面的异常try catch无法捕获

try {
  setTimeout(() => {
    undefined.map(v => v);
  }, 1000)
} catch(e) {
  console.log("捕获到异常:", e);
}
  1. async await异步请求
  2. 正则表达式处理
  3. buffer处理

Promise异常:

注意未被捕获的promise异常会作为全局异常抛出。

  1. 局部Promise捕获两种方式:
javascript 复制代码
// 1. Promise().catch()
let promise = new Promise((resolve,reject)=>{}).catch(e=>{
   // handle error
})

// 2. async/await + try/catch
let promise = new Promise();
async function test() {
  try {
    await promise;
  } catch (e) {
    // handle error
  }
}
  1. 用Promise().catch(),
  2. 全局Promise异常用window.addEventListener("unhandledrejection")

注意:

  1. Promise自己的异常只能被自己catch, 或在try/catch里以await的方式调用来捕获。否则就会作为ERR_UNHANDLED_REJECTION异常抛出到全局。
  2. 外层Promise不能不能捕获内层Promise的异常。
javascript 复制代码
let p1 = new Promise(async (resolve, reject) => {
  return reject(100); // 被捕获
});
async function fn() {
  try {
    let result = await p1;
    console.log(2, result); //这里不会执行
  } catch (e) {
    console.log("e:", e); //这里不会执行
  }
}
fn();
javascript 复制代码
let p1 = new Promise(async (resolve, reject) => {
  return reject(100); // 未被捕获,会抛出全局异常:ERR_UNHANDLED_REJECTION
});
function fn() {
  try {
    let result = p1;
    console.log(2, result); //这里不会执行
  } catch (e) {
    console.log("e:", e); //这里不会执行
  }
}
fn();
javascript 复制代码
let p1 = new Promise(async (resolve, reject) => {
  console.log("after reject");
  return Promise.reject(100); // 未被捕获,会抛出全局异常:ERR_UNHANDLED_REJECTION
});
async function fn() {
  try {
    let result = await p1;
    console.log(2, result); //这里不会执行
  } catch (e) {
    console.log("e:", e); //这里不会执行
  }
}
fn();
javascript 复制代码
let p1 = new Promise(async (resolve, reject) => {
  return Promise.reject(100); // 未被捕获,会抛出全局异常:ERR_UNHANDLED_REJECTION
}).catch((e) => {
  console.log("promise out e", e); // 这里不会执行
});
async function fn() {
  try {
    let result = await p1;
    console.log(2, result); //这里不会执行
  } catch (e) {
    console.log("e:", e); //这里不会执行
  }
}
fn();
  1. Promise里同步抛出的异常,会触发Promise.reject而被捕获。但异步抛出的异常,不会触发Promise.reject,因此不会被捕获。
javascript 复制代码
new Promise((resolve, reject) => {
  throw new Error("Error1"); // 等效于reject
}).catch((e) => {
  console.log("异常被捕获到了1");
});

new Promise(async (resolve, reject) => {
  reject(new Error("Error2"));
}).catch((e) => {
  console.log("异常被捕获到了2");
});

new Promise(async () => {
  throw new Error("Error3");
}).catch((e) => {
  console.log("异常被捕获到了3");
});

接口请求异常:

  1. Fetch 用async await + try catch
  2. Axios 请求,自行处理自定义的异常上报

全局静态资源异常监控:

window.addEventListener("error") 或者资源标签的onError属性

相关推荐
4SAPI10 小时前
AI 数据分析工具大模型 API 选型指南
大数据·人工智能·架构·php·1024程序员节
空中湖11 小时前
用 React 写数据大屏:为什么我不建议用图表库
前端·react.js·前端框架
4SAPI11 小时前
搭建 AI 数据分析工具大模型 API 选型指南
数据库·人工智能·架构·php·1024程序员节
行者全栈架构师12 小时前
【鸿蒙心迹】让老照片变清晰:HarmonyOS 7.0 图像超分相册工程化落地与 5 个踩坑解法
架构·前端框架·开源
再__努力1点12 小时前
RK3576/RV1126B多路视频 AI 开源引擎 CosmoEdge:从模型到交付,轻松搞定!
人工智能·opencv·计算机视觉·架构·课程设计
用户0942485680312 小时前
第7章:Redis有序集合 ZSet 实战:排行榜与延时任务
redis·架构·源码
欣欣之王来了12 小时前
原始HTML插值:v-html指令的使用与安全风险
前端·学习·架构·项目·vue3教程
阿文和她的Key14 小时前
PHP2Shell事故四层拆解:AI找洞是小时级,披露协调还是邮件级
网络·人工智能·架构·php
forest_0915 小时前
用Python复刻ClaudeDuet:主动式Agent四件套,定时晨报、后台巡检、危险动作审批(附完整可运行代码)
人工智能·python·架构·prompt·agi
幻智星科技16 小时前
多通道数据采集中collect_end信号的妙用
网络协议·架构·udp·硬件架构