Catch block async promise doesn't work


#1

I have a provider which am implementing async in all HTTP requests, to an async function in the page. However apparently the catch block in the provider doesn’t work, but the catch in the page works. Any reason why?

Provider function

async login(form: object) {
    try {
      let headers = await this.getHeaders();
      let response = await this.http.post(this.url + ApiList.login, form, { headers: headers }).toPromise();
      console.log("Am in promise"); //Doesn't appear if above promise is rejected
      return response;
    } catch (error) {
      console.log("Am here"); //Doesn't appear at all
      throw new Error("Am here"); //I thought the catch in the page worked because of this, but apparently it's not working at all
    }
  }

And here’s the page function that’s calling it.

async login() {
      try {
        let response = await this.api.login(this.form.value).then(response => response.json());
      } catch (e) {
        let message = await this.translate.get('Log in failure toast').toPromise();
        loader.dismiss();
        let toast = this.toastCtrl.create({
          message: message,
          duration: 3000,
          position: 'bottom'
        });
        toast.present(); //Always shows in case of promise reject | failure
      }
    }
  }

I want to understand why this is happening and to find a way to have the catch in the provider work first, then I can throw an error or return a promise reject from there


#2

Don’t nest async calls. It’s an antipattern that will kick your butt.

General comment: async/await tends to encourage antipatterns, I believe. I ditched it for Promises and Observables, and my code is much cleaner now.

I would solve your problem by refactoring to Promises, and then having the provider return a Promise.


#3

@AaronSterling, know of any good tutorials that speak to creating one’s own promises? Good as in, make sense to someone who doesn’t already know how to do it!

I’ve tried my hand many times but it’s escaping me, and you know, 99% of the tutorials out there tend to use the definition in the definition.

Any suggestions = many thanks.


#4

This one looks like a pretty good place to start.


#5

A couple tips:

DO NOT DO:

Never nest a promise inside another promise.

DO NOT DO #2:

promise1.then()
            .catch() // too many catch statements, similar problem to your code
            .then()
            .catch()

OK TO DO:

Chain promises (so the next one starts only after the current one finishes) with a single catch statement at the end.


#6

Thanks, @AaronSterling


#7

It is really rare that you will need to be creating your own promises in an Angular app. 98% of the time they will be born out of an external source such as Http or ionic-native.


#8

Duly noted. I tend to either operate on or be a victim of that 2% rule. There may be a correlation there worth considering…

I also tend to build XMLHttpRequests from the ground up, as well as make other things harder on myself in hopes it’ll make me a better programmer, while not ignoring http.get. Just use it few and far between.

Exercise in futility?


#9

Pretty much. I think you would learn more by reading how Angular’s HttpClient is written than by trying to reinvent it.


#10

Wise. I’ll kick that habit to the curb and focus on the wheel.

Sincerely, thank you. Habit = dropped.


#11

In my first application I used promises and observables, but I find async/await to be much cleaner. I admit that observables and promises give much more control than async/await, but for now, is there no fix for what I did? And I still don’t understand why exactly it’s not working, could you give me a link to read about it?

EDIT: So from what I understood, having a trycatch inside both the provider and the page is an anti pattern because it’s like nesting promises. So this is my new provider function

async login(form: object) {
    let headers = await this.getHeaders();
    let response = await this.http.post(this.url + ApiList.login, form, { headers: headers }).toPromise();
    //Some code that uses response
    return response;
  }

Am handling the catch in the page catch only, is this the correct way?


#12

I don’t mean this as snarky, though it might sound that way in text. I think you should ask someone who agrees with you that async/await is better. My experience with it has been bad, which might be partly due to my lack of skill. Sorry, and good luck.


#13

Thanks for the honesty, I understand where you’re coming from, it’s a preference, I guess.