'How do I actually catch an exception triggered by an NGXS dispatch?
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?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|