我如何实际捕获 NGXS 调度触发的异常?

发布于 2025-01-13 07:01:51 字数 2439 浏览 0 评论 0原文

我们的项目有一个系统,如果未处理的异常到达根目录,该系统会向用户显示错误模式。 (如果重要的话,它位于 AppModule@NgModule 中的 providers: [{provide: ErrorHandler, useClass: OurHandler}] 中,其中OurHandlerhandleError 显示适当的模式。)

捕获异常通常会阻止模式。但由于某种原因,在 NGXS 调度的情况下,我所做的一切似乎都没有真正捕获异常。

一些有效的代码,作为背景:

@Injectable({ providedIn: 'root' })
class ApiService {

  constructor (private readonly http: HttpClient) {}

  doTheThing(params: Foo): Promise<string> {
    return this.http.post<string>(aUrl, params).toPromise();
  }
}

@State<ThingDoingModel>({ name: 'doing' }) // there's also some defaults here
@Injectable()
export class ThingDoingState {

  constructor (private readonly apiService: ApiService) {}

  @Action(DoTheThing)
  doTheThing(ctx: StateContext<ThingDoingModel>, { foo }: DoTheThing): Promise<string> {
    return this.apiService.doTheThing(foo);
  }
}

@Component({ /*…*/ })
class ThingComponent {

  constructor (private readonly store: Store) {}

  onSubmit() {
    this.store.dispatch(new DoTheThing(this.foo)).subscribe(() => {
      this.showSuccessModal();
    });
  }
}

这一切都很完美——只要做事成功。但是,有时 POST 可能会收到错误响应。所以我想抓住这一点,并调用 this.showErrorModal(error.message) 。这也不难,但无论我做什么,异常都会不断出现,因此我也得到了默认的未处理错误模式。

我尝试过的事情:

  onSubmit() {
    this.store.dispatch(new DoTheThing(this.foo))
      .pipe(
        catchError(err => {
          this.showErrorModal(err.message);
          return EMPTY;
        }),
      )
      .subscribe(() => {
        this.showSuccessModal();
      });
  }
  onSubmit() {
    try {
      this.store.dispatch(new DoTheThing(this.foo)).subscribe(() => {
        this.showSuccessModal();
      });
    }
    catch (err) {
      this.showErrorModal(err.message);
    }
  }
  onSubmit() {
    this.store.dispatch(new DoTheThing(this.foo)).toPromise()
      .then(() => {
        this.showSuccessModal();
      })
      .catch(err => {
        this.showErrorModal(err.message);
      });
  }

但是这些都没有真正捕获 HttpClient 获得 500 响应时抛出的异常。它们大部分都有效 - 实际的 try/catch 版本没有显示我想要的错误模式,但其他版本却显示了 - 但在所有这些中,我还得到了第二个模式我不想要。

那么我如何和/或在哪里实际捕获这个异常呢?

Our project has a system that displays an error modal to the user if an unhandled exception makes its way to the root. (If it matters, this sits in providers: [{provide: ErrorHandler, useClass: OurHandler}] in AppModule’s @NgModule, where OurHandler’s handleError displays the appropriate modal.)

Catching an exception prevents the modal—usually. But for some reason, nothing I do seems to actually catch the exception in the case of an NGXS dispatch.

Some code that works, for background:

@Injectable({ providedIn: 'root' })
class ApiService {

  constructor (private readonly http: HttpClient) {}

  doTheThing(params: Foo): Promise<string> {
    return this.http.post<string>(aUrl, params).toPromise();
  }
}

@State<ThingDoingModel>({ name: 'doing' }) // there's also some defaults here
@Injectable()
export class ThingDoingState {

  constructor (private readonly apiService: ApiService) {}

  @Action(DoTheThing)
  doTheThing(ctx: StateContext<ThingDoingModel>, { foo }: DoTheThing): Promise<string> {
    return this.apiService.doTheThing(foo);
  }
}

@Component({ /*…*/ })
class ThingComponent {

  constructor (private readonly store: Store) {}

  onSubmit() {
    this.store.dispatch(new DoTheThing(this.foo)).subscribe(() => {
      this.showSuccessModal();
    });
  }
}

This all works perfectly—so long as doing the thing is successful. However, sometimes the POST might get an error response. So I want to catch that, and call this.showErrorModal(error.message). That isn’t hard either—but no matter what I do, the exception keeps bubbling up so I also get our default unhandled error modal.

Things I’ve tried:

  onSubmit() {
    this.store.dispatch(new DoTheThing(this.foo))
      .pipe(
        catchError(err => {
          this.showErrorModal(err.message);
          return EMPTY;
        }),
      )
      .subscribe(() => {
        this.showSuccessModal();
      });
  }
  onSubmit() {
    try {
      this.store.dispatch(new DoTheThing(this.foo)).subscribe(() => {
        this.showSuccessModal();
      });
    }
    catch (err) {
      this.showErrorModal(err.message);
    }
  }
  onSubmit() {
    this.store.dispatch(new DoTheThing(this.foo)).toPromise()
      .then(() => {
        this.showSuccessModal();
      })
      .catch(err => {
        this.showErrorModal(err.message);
      });
  }

But none of these actually catch the exception thrown when the HttpClient gets a 500 response. They mostly work—the actual try/catch version didn’t display the error modal I wanted, but the others did—but in all of these I also get the second modal that I do not want.

So how and/or where do I actually catch this exception?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文