”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > GlobalErrorHandler:捕获从 ErrorBoundary 手中落下的错误!

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

发布于2024-11-07
浏览:404

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(null);
  const [isDialogOpen, setDialogOpen] = useState(false);

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

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

  return (
    
      {children}

      {isDialogOpen && error && (
        
      )}
    >
  );
}

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

处理错误

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

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

通常这些信息也可以在错误对象中找到,但我需要对此进行更多的实证调查。也许我们总是应该保留错误事件报告的行号和列号?在这种情况下,我们还可以在 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;
    }

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

    function handleUnhandledRejection(event: PromiseRejectionEvent) {
      setError(`Unhandled promise rejection: ${event.reason}`);
      setDialogOpen(true);
    }

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

    window.addEventListener('error', handleWindowError);
    window.addEventListener('unhandledrejection', handleUnhandledRejection);

    return () => {
      window.removeEventListener('error', handleWindowError);
      window.removeEventListener(
        'unhandledrejection',
        handleUnhandledRejection
      );
    };

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

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

版本声明 本文转载于:https://dev.to/lebbe/globalerrorhandler-catch-the-errors-that-falls-through-errorboundarys-fingers-3m5d?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 以下是一些适合您文章的基于问题的标题:

* 如何在 PHP 中将 dd/mm/yyyy 转换为 yyyy-mm-dd:简单指南
* PHP 日期格式转换:dd/mm/yyyy 到 yyyy-mm-dd - 最佳方法
    以下是一些适合您文章的基于问题的标题: * 如何在 PHP 中将 dd/mm/yyyy 转换为 yyyy-mm-dd:简单指南 * PHP 日期格式转换:dd/mm/yyyy 到 yyyy-mm-dd - 最佳方法
    PHP 日期格式转换:dd/mm/yyyy 到 yyyy-mm-dd在 dd/mm/yyyy 和 之间转换日期格式yyyy-mm-dd 在 PHP 中可能具有挑战性。问题:使用 dd/mm/yyyy 格式的日期时会出现主要问题。由于斜杠分隔符 (/) 造成歧义,PHP 通常采用美国 m/d/y 格式...
    编程 发布于2024-11-07
  • 为什么Go函数中修改指针有时不影响原值?
    为什么Go函数中修改指针有时不影响原值?
    Go中指针的修改,理解差异在Go中,当将指针传递给函数时,我们通常会修改值该指针所指向的。通常,这可以通过取消引用来实现,如以下代码所示:type Test struct { Value int } func main() { i := Test{2} p := &i...
    编程 发布于2024-11-07
  • 周构建互动游戏
    周构建互动游戏
    第 2 周:构建互动游戏 第三课:游戏物理与运动 3.1 理解游戏物理 游戏物理涉及模拟现实世界的物理,使游戏更加真实和引人入胜。速度、加速度和重力等基本物理原理可以使游戏中的动作和交互感觉自然。 3.1.1 速度和加速度 速度是物体...
    编程 发布于2024-11-07
  • 如何使用 BeautifulSoup 从 Python 中的 HTML 表中提取数据?
    如何使用 BeautifulSoup 从 Python 中的 HTML 表中提取数据?
    BeautifulSoup解析表在Python中,BeautifulSoup提供了强大的解析HTML文档的方法。当遇到这样的场景,您需要从表中检索特定数据时,BeautifulSoup 就派上用场了。要提取目标行项目表,请使用 soup.find(),在表中指定适当的属性括号。在这种情况下,您需要:...
    编程 发布于2024-11-07
  • 如何在react中使用PKCE实现oAuth以进行第三方集成
    如何在react中使用PKCE实现oAuth以进行第三方集成
    在为第三方集成实现oAuth时,我偶然发现了一些很长一段时间没有更新的信息。在这里,我试图记录我的经验及其运作方式 注意:本文不会详细讨论oAuth及其工作原理。主要关注如何在 React 应用程序中配置和实现它们。如果您想了解 oAuth,请阅读此处。提供清晰的信息。 流程: 大...
    编程 发布于2024-11-07
  • 为什么我在 POST Jersey 请求中收到不支持的媒体类型错误?
    为什么我在 POST Jersey 请求中收到不支持的媒体类型错误?
    POST Jersey 请求中不支持的媒体类型错误遇到 HTTP 状态代码 415 - 对 Jersey 的 POST 请求中不支持的媒体类型REST 服务,问题通常在于 Jersey 发行版中缺少 JSON/POJO 支持。要解决此错误,需要在项目中添加必要的 JAR 依赖项。具体来说,需要以下依...
    编程 发布于2024-11-07
  • 针对 XSS 的常见防御措施有哪些?
    针对 XSS 的常见防御措施有哪些?
    针对 XSS 的常见防御输入和输出清理是防止跨站脚本 (XSS) 攻击的关键技术。本文探讨了行业和个人网站广泛采用的减轻这种威胁的方法。1。 HTML 转义:在将所有用户输入显示为 HTML 代码之前彻底转义它们。这涉及将“”、“&”和“等字符替换为其相应的 HTML 实体(例如,“”、“&”、“”...
    编程 发布于2024-11-07
  • Python垃圾收集器如何自动管理内存?
    Python垃圾收集器如何自动管理内存?
    Python 垃圾收集器文档Python 垃圾收集器是一个内存管理系统,可以自动释放程序不再使用的内存。这有助于通过防止内存泄漏并确保程序不会耗尽内存来提高性能。垃圾收集器的工作过程分为两步:引用计数: 解释器跟踪每个对象的引用数量。当引用计数达到零时,该对象被认为不可达,并被添加到要删除的对象列表...
    编程 发布于2024-11-07
  • PHP 如何高效处理大整数?
    PHP 如何高效处理大整数?
    PHP 可以处理大整数吗?PHP 可能没有显式的“BigInteger”类,但它提供了几种处理大整数的方法使用 BC 数学函数PHP 提供 BC 数学函数,如 bcadd() 和 bcsub() 进行整数运算。然而,这种方法对于大量计算来说可能会很慢。使用 GMP 扩展GMP(GNU 多精度算术)是...
    编程 发布于2024-11-07
  • 如何使用 Python 字符串匹配验证 IP 地址输入?
    如何使用 Python 字符串匹配验证 IP 地址输入?
    使用 Python 验证 IP 地址输入验证用户输入的 IP 地址在各种应用中至关重要。本文将探讨验证以字符串形式提供的 IP 地址合法性的最有效方法。首选方法偏离解析,而是利用 Python 标准库的套接字模块。通过利用 inet_aton(),我们可以确定输入字符串是否代表有效的 IP 地址:i...
    编程 发布于2024-11-07
  • 那么 Pull 请求如何再次发挥作用呢?屏显#3
    那么 Pull 请求如何再次发挥作用呢?屏显#3
    在我之前的文章中,我谈到了启动一个基于开源 GenAI 的终端应用程序。本周的任务是为另一个用户的项目贡献一个新功能。由于我们必须与新人合作,所以我与 Lily 合作,她开发了一款应用程序,其代码改进功能与我的类似,只是她的角色是老鼠! 有时间的话可以去看看她的项目老鼠助手。 她的代码是用 Type...
    编程 发布于2024-11-07
  • 为什么 Go 中不能直接将 []string 转换为 []interface{}?
    为什么 Go 中不能直接将 []string 转换为 []interface{}?
    为什么将 []string 转换为 []interface{} 会在 Go 中引发编译错误转换字符串切片 ([]string)考虑到它们共享切片特征以及 []string 的每个元素都可以被视为一个接口,Go 中的接口切片 ([]interface{}) 似乎很简单。然而,尝试这种转换时会出现编译错...
    编程 发布于2024-11-07
  • 理解 Shadow DOM:封装 Web 组件的关键
    理解 Shadow DOM:封装 Web 组件的关键
    在现代 Web 开发中,创建可重用和可维护的组件至关重要。 Shadow DOM 是 Web 组件标准的一部分,在实现这一目标方面发挥着至关重要的作用。本文深入探讨了 Shadow DOM 的概念、它的优点以及如何在您的项目中有效地使用它。 什么是 Shadow DOM? Shado...
    编程 发布于2024-11-07
  • 如何使用 Java 运行时解决输出重定向问题?
    如何使用 Java 运行时解决输出重定向问题?
    使用 Runtime 的 exec() 方法解决输出重定向问题在 Java 中,利用 Runtime.getRuntime().exec() 运行命令可以捕获进程的输出和错误流。但是,在需要输出重定向的情况下,单独使用此方法可能无效。问题:输出未重定向当使用 Runtime.getRuntime()...
    编程 发布于2024-11-07
  • 如何使用 CSS 悬停效果从左到右填充背景颜色?
    如何使用 CSS 悬停效果从左到右填充背景颜色?
    使用 CSS 从左到右填充背景颜色在 CSS 中,您可以通过利用线性渐变和动画背景定位来创建迷人的悬停效果。这种方法使您能够在悬停时从左到右用新颜色填充元素的背景。线性渐变和背景大小关键是使用由两种颜色组成的线性渐变背景,并将背景大小设置为元素宽度的两倍。这允许您在两种颜色之间创建无缝过渡。背景定位...
    编程 发布于2024-11-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3