Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

稳定性第一步:认识error #87

Open
wuyunqiang opened this issue Nov 11, 2024 · 0 comments
Open

稳定性第一步:认识error #87

wuyunqiang opened this issue Nov 11, 2024 · 0 comments

Comments

@wuyunqiang
Copy link
Owner

先有问题再有答案

  1. 如何理解error对象?
  2. error对象如何使用 有哪些属性?
  3. web有哪些error?
  4. 资源异常, 网络异常, 解析异常, 运行时异常, 渲染异常 这些异常是如何产生的?
  5. 异常可以分为哪些类型?
  6. 如何理解同步异常,异步异常?

error对象

在 JavaScript 中,Error 对象是一个内置的对象类型,它是用来表示在程序执行期间发生的错误信息的。

当运行时错误发生时,JavaScript 会自动创建并抛出一个 Error 对象。

开发者也可以在代码中手动创建并抛出Error对象,来处理预期的错误或异常情况。

基本属性

Error 对象通常包含以下几个基本属性:

  1. message:一个字符串,表示错误的具体信息。
  2. name:错误的类型名称,默认是 "Error"。其它常见的错误类型还有 "TypeError", "ReferenceError" 等。
  3. stack(非标准,但大多数环境支持):一个字符串,表示错误发生时的调用栈信息。
    try {
        const p = 12;
        p();
    } catch (error) {
        console.log('Error: ', error);
        console.log('Error JSON: ', JSON.stringify(error));
        console.log('Error name: ', error.name);
        console.log('Error message: ', error.message);
        console.log('Error stack: ', error.stack);
    }

截屏2024-08-23 17.01.54.png

不可枚举

JSON.stringify(error) 尝试将错误对象转换为 JSON 字符串。然而,标准的 Error 对象包含的属性(比如 message 和 stack)在 JSON.stringify 调用时通常是不可枚举的,因此这行代码输出 {}。

可抛出(throw)/可捕获(try catch)

在 JavaScript 中,Error 对象、throw 语句和 try...catch 结构是紧密关联的,用于处理和控制程序执行过程中的异常情况。

    try {
        throw 3;
        // throw new Error(3)
    } catch (error) {
        console.log('Error: ', error);
        console.log('Error JSON: ', JSON.stringify(error));
        console.log('Error name: ', error.name);
        console.log('Error message: ', error.message);
        console.log('Error stack: ', error.stack);
    }

截屏2024-08-23 17.26.49.png

虽然通常推荐抛出 Error 对象(因为它们提供了错误名称、消息和堆栈跟踪等有用的信息帮助调试),但 JavaScript 的灵活性允许使用 throw 抛出任何类型的值。

        throw 3;
        throw new Error(3);
        throw {name: '自定义错误', message: '这是一个自定义错误信息'};
        throw ()=>{
            console.log('一个函数')
        }; 

异常类型

Web 开发中可以从不同的角度进行异常分类,例如以下几种:

按照异常的运行时机

同步异常
同步异常是在执行同步代码时发生的,也就是说,在执行当前代码块的过程中发生了错误,并且错误发生在发出错误指令的同一个线程中。在同步代码中,可以通过常规的try...catch语句捕获这些异常。

异步异常
异步异常是在执行异步操作(如setTimeout、Promise等)过程中发生的。由于 JavaScript 的事件循环和非阻塞特性,这些错误不会立即在执行时被捕获。它们通常需要特定的错误处理方式,如在Promises中使用.catch()方法,或在使用async/await时结合try...catch。

new Promise((resolve, reject) => {
    setTimeout(() => {
        try {
            throw new Error('Something went wrong');
        } catch(e) {
            reject(e);
        }
    }, 2000);
}).catch((error) => {
    console.log(error.message);  // 输出:Something went wrong
});

在上面的例子中,我们创建了一个新的Promise,它在2秒钟后抛出一个错误。 该错误已经被我们catch到,并且用reject将其传到Promise的catch方法中。

错误产生的阶段

截屏2024-08-29 15.45.49.png
资源异常

在浏览器加载网页时,会尝试加载和解析各种资源,包括 JavaScript、CSS、HTML、图片等。在这个过程中,可能会遇到各种问题导致加载失败,这就会出现所谓的资源加载异常。以下是一些可能出现这种异常的情况:

  1. CDN(内容分发网络):CDN通过在各地设立节点服务器,复制源服务器上的内容,当用户请求数据时,CDN会将请求重新导向离用户最近的节点,从而加快加载速度和提高访问质量。如果CDN节点出现故障或不可访问,或者CDN无法正确地将请求引导到正确的节点,都可能造成资源加载异常。

  2. OSS(对象存储服务):OSS服务用于存储大量不可更改的数据,比如网页上用到的图片、视频等。如果OSS服务出现故障,或者存储的数据被删除或损坏,都会导致网页无法正常加载资源。

  3. 服务器不存在或者服务器错误:当您的站点尝试加载一个不存在的服务器上的资源,或者服务器返回错误(如500错误——内部服务器错误)时,就会出现资源加载异常。

网络异常

  1. API执行异常:当执行 AJAX、fetch 请求或 WebSocket 连接等网络操作时,可能会因为网络问题或服务器问题导致异常,比如 404 错误、超时等。
  2. 网络环境:用户的网络环境会直接影响资源加载的速度和质量。如果网络慢、不稳定或者被阻断,就会出现资源加载失败的情况。此外,一些网络提供商可能会对某些类型的流量进行限制,比如对视频流量进行限速,也可能导致资源加载异常。
  3. DNS解析错误:DNS将网址解析为服务器的IP地址。如果DNS服务器出现故障或者DNS解析过程中出现问题,可能会导致网络异常。
  4. ISP问题:ISP(互联网服务提供商)可能会由于内部问题,如硬件故障、网络配置错误等,导致网络异常。
  5. 防火墙、安全软件拦截:部分安全软件或者防火墙可能会阻止或者限制网络连接,从而导致网络异常。
  6. 网络配置错误:如IP冲突,子网掩码设置错误,网关设置错误等,也会导致网络异常。

解析异常:

当浏览器解析 HTML、CSS 或 JavaScript 代码时(由于语法错误等原因)出错,会导致解析异常。

截屏2024-08-23 20.37.04.png
例如上述代码 浏览器无法解析ts代码 会导致解析异常, 这种异常一般不会出现在线上 因为都会经过打包编译 但是线上一旦出现这种问题 将是灾难性的...

运行时异常:

当 JavaScript 代码在运行时出现错误,比如引用了未定义的变量,或者调用了不存在的函数等。

为了解决这类兼容性问题,开发者通常需要在编程时进行特性检测,判断浏览器是否支持某个特性;或者使用Polyfill库,比如core-js或babel-polyfill,它们提供了新的API在旧的浏览器中的实现,能够填充这些功能的空白。同时,对于关键的功能代码,也可以考虑使用try/catch来捕获并处理可能出现的异常。

这类问题也是导致页面白屏的常见原因之一,关于白屏参考: 白屏根因分析&检测

渲染异常:

渲染异常也属于运行时异常的一种情况,在React和Vue等前端框架中,如果在渲染过程中由于各种原因(比如数据格式不符合预期等)导致JS代码出现错误,可能会导致页面渲染失败。这种失败的结果表现形式可能是部分组件无法正确显示,也有可能是整个应用崩溃。

React有一个特性叫做错误边界(Error Boundaries),可以把这些在渲染期间、生命周期方法中、以及整个组件树的构造函数中发生的错误捕获到,并且这些错误会阻止整个React组件树的渲染。

Vue中也有类似的特性,可以通过 errorCaptured 钩子和全局的 errorHandler 处理函数来捕获和处理异常。

按错误的严重性

致命错误

这类错误通常会导致程序崩溃,渲染失败白屏,终止运行。 例如上面的解析异常,渲染异常大部分时间都是致命的....

非致命错误

虽然发生了错误,但程序可以继续运行,可能会降低性能或影响用户体验, 例如某些点击事件运行报错 但不影响业务的主要流程...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant