在nodejs & 浏览器端中如何进行全局错误捕获?

223 阅读2分钟

业务开发中,我们常常需要对应用的代码执行异常进行上报&分析,一般会采用对全局的错误进行捕获和上报的方式。 那问题来了从全局维度应用的异常可以怎么捕获和监听到呢?

本文将详解描述在nodejs & 浏览器端中如何进行错误捕获:

一、nodejs环境全局错误捕获

1. 一般代码执行流程中

1.1 uncaughtException

// 捕获未处理的异常
process.on('uncaughtException', (err) => {
    console.error('Uncaught Exception', err);
    // 你可以在这里执行一些清理操作,然后退出进程
    process.exit(1);
});

throw new Error('This is an uncaught exception');

1.2 unhandledRejection

process.on('unhandledRejection', (reason, promise) => {
    console.error('Unhandled Rejection at:', promise, 'reason:', reason);
    // 你可以在这里执行一些清理操作,然后退出进程
    process.exit(1);
});

Promise.reject('77777');

!!! 注意: 在nodejs 14版本后 属于unhandledRejection的错 如果没有被unhandledRejection捕获,也会被uncaughtException的监听捕获

2.nodejs的web服务器中

2.1 express

在 Express 中,可以通过定义一个错误处理中间件来捕获和处理所有未处理的错误。

const express = require('express');
const app = express();

// 示例路由
app.get('/', (req, res) => {
    throw new Error('Something went wrong!');
});

// 全局错误处理中间件
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Something broke!');
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

2.2 koa

可以通过 app.on('error', ...) 监听错误事件。

const Koa = require('koa');
const app = new Koa();

// 全局错误处理中间件
app.use(async (ctx, next) => {
    try {
        await next();
    } catch (err) {
        console.error(err.stack);
        ctx.status = err.status || 500;
        ctx.body = 'Something broke!';
        ctx.app.emit('error', err, ctx);
    }
});

// 示例路由
app.use(async (ctx) => {
    ctx.throw(500, 'Something went wrong!');
});

// 错误事件监听器
app.on('error', (err, ctx) => {
    console.error('Server error', err, ctx);
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

二、浏览器端全局错误捕获

1.使用 window.addEventListener 监听 error 事件

是一个全局错误处理器,可以捕获未处理的错误。它可以捕获运行时错误和语法错误。

window.addEventListener('error', function(event) {
    console.error("Error message: " + event.message);
    console.error("Source: " + event.filename);
    console.error("Line: " + event.lineno);
    console.error("Column: " + event.colno);
    console.error("Error object: " + event.error);
    // 返回 true 可以阻止默认的错误处理(即在控制台中显示错误)
    return true;
});

2.捕获未处理的 Promise 拒绝(rejection)

对于未处理的 Promise 拒绝,可以使用 window.addEventListener 监听 unhandledrejection 事件。

window.addEventListener('unhandledrejection', function(event) {
    console.error("Unhandled rejection: " + event.reason);
    // 返回 true 可以阻止默认的错误处理(即在控制台中显示错误)
    return true;
});

3.使用第三方库

可以使用一些第三方库来捕获和处理错误,例如 Sentry、TrackJS 等。这些库提供了更强大的错误捕获和报告功能。