Roaders
Roaders

Reputation: 4545

How to find which initial value in an RxJs stream produced an error

I have a service that returns a list of mail servers for an email address:

export interface IMailServerService {
    lookupMailServers( contact: IHasEmail ): RX.Observable<IHasMailServer>;
}

and I use this service to get mail servers for a list of contacts:

checkContacts( contacts: Array<contracts.IContact> ): void {
    Rx.Observable.from(contacts).flatMap<contracts.IHasMailServer>( (contact) => {
        return this._mailServerService.lookupMailServers( contact )
    } ).subscribe(
        (result) => this.handleResult(result),
        (error) => this.handleError(error)
    );

This works fairly well apart from handling errors. In my error handler I want to log the error but also the contact that produced the error. Is there any way I can get hold of the contact object that the error relates to or do I have to throw a custom error in my service that includes the contact that the error is for?

The code for this example can be seen here:

https://github.com/Roaders/contact-list-checker/tree/4dd0146449a4be6e703a9b60034231cc4c4bdea3

Upvotes: 0

Views: 95

Answers (1)

Roaders
Roaders

Reputation: 4545

The answer seems to be that you can't do this in the way I was expecting. You have to handle it within the mailServerService and throw a custom error:

lookupMailServers( email): Rx.Observable<contracts.IHasMailServer> {

    return Rx.Observable.fromNode()
        .catch( (error) => {
            console.log( `Error getting mail server for domain ${domain} on email ${email.email}: ${error}` )
            return Rx.Observable.throw<contracts.IHasMailServer>( <contracts.IMxLookupError>{ error: error, hasEmail: email } );
        } );
}

and then in my other class you can access the IMxLookup error:

    Rx.Observable.from(contacts).flatMap<contracts.IHasMailServer>( (contact) => {
        return this._mailServerService.lookupMailServers( contact )
            .retry(3)
            .catch((error: contracts.IMxLookupError ) => {
                console.log(`Error loading mx servers for email ${error.hasEmail.email}: ${error.error}`);
                return Rx.Observable.empty<contracts.IHasMailServer>();
            });
    } ).subscribe(
        (result) => this.handleContactWithMailServer(result),
        (error) => this.handleMailServerError( error )
    );

Upvotes: 1

Related Questions