首页 web前端 js教程 GlobalErrorHandler:捕获从 ErrorBoundary 手中落下的错误!

GlobalErrorHandler:捕获从 ErrorBoundary 手中落下的错误!

Oct 21, 2024 pm 08:39 PM

GlobalErrorHandler: Catch the errors that falls through ErrorBoundary

ErrorBoundary 是一个出色的工具,可以捕获 React 组件抛出的错误。您可以根据错误本身的性质和位置提供自定义错误消息。但并非所有抛出的错误都由 ErrorBoundary 处理!你用这些做什么?

当考虑异步错误和从 React 外部抛出的错误时,ErrorBoundary 不够。为了缓解这个问题,我在我的应用程序中创建了我所说的 GlobalErrorHandler。一个功能组件,只需 A) 弹出一个错误对话框,告诉用户某件事出了问题,B) 将错误记录到服务器,以便我们调查并找到解决方案。

这个想法很简单。我们希望在应用程序的根目录中有一个 GlobalErrorHandler。该处理程序应该仅处理ErrorBoundary未捕获的错误。更重要的是,它应该很容易被用户忽略,并且我们应该假设该应用程序仍然可用。

所以策略是这样的:默认情况下,除了渲染其子级之外,GlobalErrorHandler 根本不执行任何操作。但是,它设置了两个事件侦听器,侦听浏览器中的所有错误和未处理的拒绝事件。然后它检查错误,并查看是否已由任何 ErrorBoundaries 处理。最后,如果情况并非如此,它会弹出一个对话框,告诉用户某处出了问题,并让用户关闭对话框并继续使用应用程序。

错误是否已被处理

在 ErrorBoundary 处理之上使用不必要的对话框来困扰最终用户之前,我们首先必须首先询问错误:您已经被处理了吗?我的解决方案是在错误对象 isHandledByBoundary 上引入一个新字段。这在 ErrorBoundary 中设置为 true:

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    (error as any).isHandledByBoundary = true;
    ....
  }
登录后复制
登录后复制

在所有 ErrorBoundary 组件(以及处理未捕获错误的其他机制)中使用此功能后,我们就可以开始定义 GlobalErrorHandler。

裸露的骨架

然后我们可以构建 GlobalErrorHandler 的骨架。它直接呈现其子项,并且还呈现在其他地方定义的“ErrorDialog”。 (如果您想跨应用程序共享此组件,则 ErrorDialog 可以是一个 prop。)

import { useState, useEffect, ReactNode } from 'react';
import { ErrorDialog } from '../Components/ErrorDialog';

type Props = {
  children: ReactNode;
};

export function GlobalErrorHandler({ children }: Props) {
  const [error, setError] = useState<Error | string | null>(null);
  const [isDialogOpen, setDialogOpen] = useState(false);

  useEffect(() => {
    ....
  }, []);

  function handleCloseDialog() {
    setDialogOpen(false);
    setError(null);
  }

  return (
    <>
      {children}

      {isDialogOpen && error && (
        <ErrorDialog
          actionName="Unhandled error"
          error={error}
          loggFeilmelding={true}
          onClose={handleCloseDialog}
        />
      )}
    </>
  );
}

登录后复制
登录后复制

我们现在唯一缺少的是错误处理本身,在 useEffect 中定义。

处理错误

本节中的所有代码都应位于 useEffect 函数内!

首先我们定义handleWindowError。这将被传递到窗口对象上的错误事件处理程序。这里没什么神秘的,但请注意错误事件还包含有关源、行号和列号的信息。这可能有收藏价值。

通常这些信息也可以在错误对象中找到,但我需要对此进行更多的实证研究。也许我们总是应该保留错误事件报告的行号和列号?在这种情况下,我们还可以在 GlobalErrorHandler 中拥有一个状态(并确保在记录错误时发送该状态)。

  componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    (error as any).isHandledByBoundary = true;
    ....
  }
登录后复制
登录后复制

我们还将定义handleUnhandledRejection 处理程序。这是针对在承诺中引发的错误,但我们忘记编写 .catch() 子句的地方。

import { useState, useEffect, ReactNode } from 'react';
import { ErrorDialog } from '../Components/ErrorDialog';

type Props = {
  children: ReactNode;
};

export function GlobalErrorHandler({ children }: Props) {
  const [error, setError] = useState<Error | string | null>(null);
  const [isDialogOpen, setDialogOpen] = useState(false);

  useEffect(() => {
    ....
  }, []);

  function handleCloseDialog() {
    setDialogOpen(false);
    setError(null);
  }

  return (
    <>
      {children}

      {isDialogOpen && error && (
        <ErrorDialog
          actionName="Unhandled error"
          error={error}
          loggFeilmelding={true}
          onClose={handleCloseDialog}
        />
      )}
    </>
  );
}

登录后复制
登录后复制

然后我们需要做的就是设置监听器,并在 GlobalErrorHandler 不再渲染时删除监听器:

   function handleWindowError(
      message: string | Event,
      source?: string,
      lineno?: number,
      colno?: number,
      error?: Error
    ) {
      if (error && (error as any).isHandledByBoundary) {
        return true;
      }

      const errorMessage = error
        ? error
        : `Error: ${message} at ${source}:${lineno}:${colno}`;
      setError(errorMessage);
      setDialogOpen(true);
      return true;
    }
登录后复制

return 语句当然是我们从提供 useEffect 的函数中返回的地方。这确保了我们在组件渲染时开始监听事件并处理它们,并在组件不再渲染时停止。

因此,我们有一个 GlobalEventHandler,来处理 React 应用程序中那些讨厌的错误,这些错误要么是从异步源抛出的,要么是从 React 组件外部抛出的!

以上是GlobalErrorHandler:捕获从 ErrorBoundary 手中落下的错误!的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1423
52
Laravel 教程
1317
25
PHP教程
1268
29
C# 教程
1243
24
神秘的JavaScript:它的作用以及为什么重要 神秘的JavaScript:它的作用以及为什么重要 Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

JavaScript的演变:当前的趋势和未来前景 JavaScript的演变:当前的趋势和未来前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript引擎:比较实施 JavaScript引擎:比较实施 Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

Python vs. JavaScript:学习曲线和易用性 Python vs. JavaScript:学习曲线和易用性 Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

JavaScript:探索网络语言的多功能性 JavaScript:探索网络语言的多功能性 Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

如何使用Next.js(前端集成)构建多租户SaaS应用程序 如何使用Next.js(前端集成)构建多租户SaaS应用程序 Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

使用Next.js(后端集成)构建多租户SaaS应用程序 使用Next.js(后端集成)构建多租户SaaS应用程序 Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

从C/C到JavaScript:所有工作方式 从C/C到JavaScript:所有工作方式 Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

See all articles