【问题标题】:Correct way to catch errors with async/await使用 async/await 捕获错误的正确方法
【发布时间】:2026-02-20 00:45:02
【问题描述】:

我有需要等待每个 HTTP 响应的应用程序。所以调用需要以特定的顺序执行,其中一些需要另一个服务的响应。我认为可以在一个地方捕获错误 - 将传播错误的根/主方法。但它似乎不是那样工作......甚至可能吗?或者这是否意味着我需要在使用 await 的每个方法中使用 try/catch 块??让我们假设这个伪代码:

user.wrapper.service.ts

// Class which wraps real UserService with HTTP calls
export class UserWrapperService {
   async getUserById(id: number): Promise<UserResponse> {
      return await this.userService.getUser(id).toPromise() as UserResponse;
   }

   async getUserDetails(userName: string): Promise<UserDetailsResponse> {
      return await this.userService.getUserDetails(userName).toPromise() as UserDetailsResponse;
   } 
}

main-component.ts

export class MainComponent implements OnInit {

   async ngOnInit() {
      try {
         await this.retrieveDetailsForEachUser();
      } catch (e) {
        this.router.navigate(['/error']);
      }
   }

   private async retrieveDetailsForEachUser(): Promise<any> {
      for (let counter = 0; counter < 10; counter++) {
         const user = await this.userWrapperService.getUserById(counter);
         console.log(user);
         const details = await this.userWrapperService.getUserDetails(user.name);
         // use this details in another service with bigger method, where is present more async/await
      }
   }
}

我希望如果UserWrapperService 的方法出现问题,错误将在MainComponent 中传播和捕获。或者至少可以以某种方式实现。但似乎我需要抛出异常并尝试/捕获所有async 方法,这些方法是awaiting。我对吗?有没有更漂亮的方法来完成这个?

【问题讨论】:

  • 嗯,我希望这能正常工作。我之前成功使用过相同的模式。关键是确保您在 try 块内使用 await,您就是这样。

标签: angular typescript error-handling async-await


【解决方案1】:

在使用 async-await 处理错误时,您必须使用 try-catch 块,并且您做得正确。对我来说唯一错误的是,您在返回异步调用结果的同时在服务方法中等待,这将返回一个Promise&lt;Promise&lt;UserResponse&gt;,这不是预期的行为。

修改您的代码以删除服务类中的await 关键字,如下所示,仅在组件类中等待。

user.wrapper.service.ts

export class UserWrapperService {
   async getUserById(id: number): Promise<UserResponse> {
      return this.userService.getUser(id).toPromise();
   }

   async getUserDetails(userName: string): Promise<UserDetailsResponse> {
      return this.userService.getUserDetails(userName).toPromise();
   } 
}

现在您将能够根据主组件类的要求捕获错误、处理错误并导航到错误页面。

【讨论】:

  • 感谢您的回答。你可能是对的,但我还有一个问题。这是否意味着我需要在我真正需要等待响应的每个地方使用try-catch 块?我说的是我在代码中的注释行。我有多个服务,它们实现了一个接口,我还需要执行一系列调用,这些调用使用之前调用的响应。
  • @Lui try-catch 块在使用 async-await 方法时不是必需的。如果你不使用它们,方法的执行会突然停止,即 await 调用下面的任何东西都不会执行。错误消息也将与堆栈跟踪一起记录在控制台中。但是用 try-catch 包装 await 调用是一个很好的做法,这样您就可以处理错误并执行与失败案例相关的一些逻辑,例如执行清理和释放不需要的资源(如果有的话)。
  • 我知道try-catch 不是必需的,但我认为在我的情况下是这样,对吧?因为,无论如何,如果出现问题,我想重定向到error 页面。目前我在控制台中看到了堆栈跟踪,正如您所提到的,等待下面的任何内容都没有执行。但同时,用户不知道出了什么问题,我需要重定向他。
  • 在这种情况下,您需要添加 try-catch 块来显示一些与用户相关的错误内容,以防出现错误。