当前位置: 首页 > 知识库问答 >
问题:

前端 - 请问一般我们应该在哪一层进行处理这个异常呢(我可以把异常弹窗展示)?

东门翰
2025-01-14

请问,我们在开发前端项目的时候:
比如要通过如下的一个栈,一层一层地请求API

组件层
store层
api层

我们知道这一串请求,达到某个层级如果崩溃的话,我们可以通过try/catch进行捕获异常,我们可以向上进行throw异常,请问一般我们应该在哪里进行处理这个异常呢? 我可以把异常弹窗展示。

共有3个答案

潘飞英
2025-01-14

这里的思路核心是:谁的异常谁处理。

比如,你有一个删除的按钮,删除的时候会弹出一个 confirm modal,然后用户点击了“确认”。那么,这个异常就是你的。如果删除失败,不管是任何一个环节失败,都应该在你的删除函数里处理。所以也应该在删除函数里捕获,其它地方都当它不会出错来跑就行,因为错误会强行清栈。

当然,有极个别的错误可以放到全局统一处理。比如 401,在请求层捕获然后跳转到登录页面或者弹出登录窗口也行。但是,我们必须考虑用户状态中途失效,而用户已经进行了一些操作需要保存这种情况,所以,我的建议仍然是,谁的错误谁处理,不要嫌麻烦。

卢黎明
2025-01-14

早先我也遇到过类似的“在哪里处理”的问题。
不过我纠结的“处理”和你的不一样,我的观点是:所有中间层都不应该把错误藏起来(你可以当它不存在,但不能 catch 了却不抛出,这样不便于 debug),除非你 try...catch 的本意就是处理程序边界,我遇到的主要问题在于:

  1. 如果在公共请求方法统一弹出信息提示用户,这样做可以确保不会落下任何错误提示,但是提示信息往往来自后端,其中满是技术术语,用户很难读取其中的有效信息;
    当然,可以让应用层调用方法的时候传一组消息模板,这样就能通过拼接消息模板和错误信息来提示用户了,但是比较繁琐,毕竟这个模板需要层层传递。
  2. 如果公共请求方法不弹提示,则很容易会有错误被疏忽,下面不管,上面也不理,用户报告问题的时候往往是“没反应”,从而导致线上问题久久无法定位具体原因。

别人的解决方法我不知道,我自己是在公共请求方法里把 Error 封装了一层,并且用 getter 拦截并检测读取信息的行为:

  • 如果外层有读取行为,就认为是在处理这个错误(让用户知晓),公共请求方法就不处理;
  • 如果外层没有读取,就认为这个错误没被处理,就择机(其实是固定延时)在公共请求方法处理。
class ResponseError {
  #message = "";
  #processed = false;
  #originError!: Error;
  #level:"info"|"warning"|"error" = "error";

  constructor(error: Error, level?: "info"|"warning"|"error"){
    this.#originError = Error;

    if(level) this.#level = level;

    setTimeout(() => {
      if(this.processed) return; // 被别处处理过了,就不用管

      // 尚未处理,弹提示信息,然后抛出
      Message[this.#level](Error.message);
      throw error;
    }, 80) // 凡在这个时间点前进行的处理,都能检测到
  }

  // 别处代码尝试读取这个信息的时候调用
  getter message(){
    this.#processed = true; // 检测到读取行为,标为已处理
    if(process.env.ENV = "development"){
      console.warn("一个错误信息被读取了,其默认提示被取消")
    }
    return this.#originError.message;
  }
}

��这只是简化的原理演示,实际上我是做了一个工厂函数返回了一个 Proxy

楼上的做法也是有参考性的, http 请求在公共请求方法里处理。但是很可惜,我们的后端把所有他能控制的错误都包装成了 500 ,只有网关的错误是正确的 http 错误,所以我必须考虑 500 状态的几乎所有可能性。

韦寒
2025-01-14

自己捕捉自己的异常。

网络请求相关的异常,统一的错误处理应该在拦截器里面配置好,并且返回好对应的 Promise 状态到调用的业务。一般我会把 401403500 之类的异常处理直接在拦截器里面配置弹窗提醒。

组件和 Store 层一般就只会有业务逻辑错误的捕捉。不会出现说某一个网络请求异常,比如说超时或者其他的原因,导致整个业务逻辑不能正常执行,在控制台抛出 throw Error

 类似资料:
  • 我搜索了很多,几乎所有我发现的例子都使用了控制器中的异常处理和自己的异常处理程序。我一直认为这应该在程序的服务层上完成。如果不是,我真的不明白为什么要创建单独的服务层。 另外,如果我在Controller中实现异常处理,是否意味着我必须在前面的所有层中抛出异常?

  • 你好,我正在学习OOP,通过编写一个虚拟的库管理项目在Java。 在serachBook()中,如果在ArrayList中找到book,则返回book对象,如果未找到,则抛出自定义异常BookNotFound。 问题1:它应该只返回null并在调用代码时检查返回值是否为null,还是抛出自定义异常BookNotFound。 目前我认为BookNotFinder是合适的,并且目前正在这样做。然而,我

  • 处理请求的过程中,Spring MVC可能会抛出一些的异常。SimpleMappingExceptionResolver可以根据需要很方便地将任何异常映射到一个默认的错误视图。但,如果客户端是通过自动检测响应的方式来分发处理异常的,那么后端就需要为响应设置对应的状态码。根据抛出异常的类型不同,可能需要设置不同的状态码来标识是客户端错误(4xx)还是服务器端错误(5xx)。 默认处理器异常解析器De

  • 1.【强制】不要捕获Java类库中定义的继承自RuntimeException的运行时异常类,如:IndexOutOfBoundsException / NullPointerException,这类异常由程序员预检查来规避,保证程序健壮性。 正例:if(obj != null) {...} 反例:try { obj.method() } catch(NullPointerException e)

  • 我正在用Python编写一个简单的API客户端,我想知道如果远程服务器不满意,我应该引发什么异常。 API本身的文档记录非常糟糕(我不知道所有可能的错误消息,所以我不能为所有这些消息定义自定义类),我让请求处理HTTP级别的错误,在这些情况下会引发,但是如果服务器在JSON响应中只提供键,我应该引发什么呢? 我目前使用的是,但感觉非常广泛,我想知道是否有更好的替代方案。 问候。

  • 我试图模拟一些静态方法,但得到以下堆栈跟踪 DAQHelper是一个静态类,它是从我当前正在测试的方法调用的。为了保持故事简短,我有一个方法addMetricData(…)调用getCategoryResource(…)等此getCategoryResource(…)是一个公共静态方法,它反过来调用getDomainResource(DAQHelper中的私有静态方法)。getDomainReso

  • 无法使用由try和catch块包围的@controlleradvice和@afterthollow when方法。 我可以一步一步解释 }