community. I have one problem. I need to log an error in Angular's error handler without closing the stream subscription when an error occurs.
I have the following data stream:
/**DATA Provider Service*/
getData(settings): Observable<any> {
return HttpClientGET$(settings).pipe(
/***/
map(response => transformMethod(response)),
/***/
tap(convertedData => sendData(convertedData))
);
}
sendData(data: any): void {
this.replaySubject.next(data);
}
getConvertedData(): Observable<any> {
this.replaySubject.asObservable();
}
/**Parent Component*/
ngOnInit(): void {
this.changePositionStream$.pipe(
switchMap((settings) => this.dataService.getData(settings))
).subscribe();
}
/**Child - Data Component*/
ngONInit(): void {
this.service.getConvertedData().subscribe();
}
Issue - an error can be caught in the Angular error handler when the error stream doesn't interrupt or use the throwError()
. But when an error is thrown the subscription is closing.
How do I log an error without closing the data subscription?
CodePudding user response:
You can use RxJS materialize to handle errors and discard them:
export const catchAndDefaultTo = <T, K>(defaultValue?: K): MonoTypeOperatorFunction<T | K> => pipe(
materialize(),
map(n => n.kind !== 'C'
? new Notification('N', n.value || defaultValue)
: n
),
dematerialize(),
)
Error notification does not have a value so n.value
will not be set here and it will create a next notification instead with whatever is set as defaultValue
. Error notification is now "discarded" and a next notification is send instead thus it will not close the stream.
I am not sure what part of your stream you want to handle so I assume somewhere here:
ngOnInit(): void {
this.changePositionStream$.pipe(
switchMap((settings) => this.dataService.getData(settings)),
catchAndDefaultTo(undefined)
).subscribe();
}
I am not 100% sure what materialize does but how I see it let's you manipulate every notification (next, error and complete) that goes through your stream.
CodePudding user response:
In the general case what you're asking isn't possible.
As per the Observable contract, once an observable has emitted an error
or complete
, then that observable is done and may never emit anything else (it's free to release any resources, etc). An observable will never error
twice, complete
twice, or both error
and complete
. Once is all it gets.
RxJS does come with a set of tools to manage errors and re-try/re-subscribe to source observables etc. We can't know from what you've written here, what would work for you, but there are many questions/answers already about how to do manage RxJS errors.