Promise in a vuex action does not work when trying to handle the http request error

0

Hello, I am developing an application in Vue.js, Nativescript and Vuex , when making an ajax request in an action return a promise to handle asynchrony the problem is that when an error is generated this It is not captured at the moment of calling the method but when everything is working well.

in the action method place a url that does not exist to lead to the error but does not pass through this, which you think it may be.

action method

CrearUsuario(context,objeto){
   console.log("el valor de objeto antes de enviar es " + JSON.stringify(objeto));
   return new Promise((resolve,reject)=>{ //usando promesas para controlar asincronia de peticion
   http.request({
                 url     : servidor + "/api/personas/thisUrlDoesntExist",
                 method  : "POST",
                 headers : { "Content-Type": "application/json" },
                 content : JSON.stringify({objeto  })

   }).then( response => { 
            console.log("estamos usando json");
            console.log("el valor total es " +  JSON.stringify(response));
            var result = response.content.toJSON();
            context.commit('SetJson',result);
            resolve(response);
            }, 
            error => {
            //console.error(error);
            reject(error);
          });
 })
}

code when calling action method

            Insertar(){
                var objeto={
                            ":PA_PAIS_ID" : this.form.txtpaisId,
                            ":PE_NOMBRE"  : this.form.txtNombre,
                            ":PE_CORREO"  : this.form.txtCorreo,
                            ":PE_CLAVE"   : this.form.txtpass
                }
                this.$store.dispatch('CrearUsuario',objeto).then(response => {                  
                  //al ser success funciona perfecto y pasa por aqui
                  console.log("terminamos la peticion");
                  this.isBusy=false;
                },
                 // al manejar error no funciona no muestra mensaje
                 error=>{
                    console.log("error en peticion " + error );
                    this.isBusy=false;
                 }
                );

            },

Finally it is worth mentioning that I am using the Nativescript http module to make the request to the server.

    
asked by jose miguel jara 17.09.2018 в 20:55
source

1 answer

1

A mutation is declared in Vuex that returns a promise. When this is resolved, the store changes its status to the value with which the promise was resolved, but for what it calls us, setting the state in vuex returns a promise:

this.$store.dispatch('CrearUsuario',objeto) // retorna una promesa

Like all promises, it exposes a then method whose first parameter should be a function that is invoked with the value with which the promise is resolved. Then:

this.$store.dispatch('CrearUsuario',objeto).then( (response) => {
  console.log('la promesa se resuelve con response:',response);
});

Until then we're fine.

Short answer

The specification of a Promise says that:

  • The promise exposes a method then
  • The then method returns a promise in itself
  • The then method accepts two parameters (functions) ( onFulfilled , onRejected )
  • The promise exposes a method catch
  • The catch method returns a promise
  • The catch method accepts a parameter (function) onRejected

Then:

this.$store.dispatch('CrearUsuario',objeto)
.then( response => { /* se invoca si todo sale bien */ },
       error => { /* podría invocarse si algo falla */ }
)
.catch( error => { /* se invoca si algo falla */ });

Apparently the http module does not take into account the second parameter of then . Never invoke onRejected but use throw and assume that you on the other side will put a catch to catch the error.

Many current bookstores follow the same practice. If the catch exists, why use the second parameter of then ?

Extended Response

As the then method returns a promise, it is clear that you can declare a chain of promises. If you have a series of functions devuelvePromesa1 , devuelvePromesa2 , devuelvePromesa3 , you can call them in series and catch all the intermediate errors with a catch final, doing:

return devuelvePromesa1(arg1)
  .then((res_prom1)=>{
    return devuelvePromesa2(res_prom1);
  })
  .then((res_prom2)=>{
    return devuelvePromesa3(res_prom2);
  })
  .then((res_prom3)=>{
    return devuelvePromesa4(res_prom3);
  })
  .catch((error)=> {
    console.error('algo falló', error);
  });

The final catch catches any errors that occur in between, no matter what happened.

But moment. Let's go back As it was said:

  

The then method accepts two parameters (functions) ( onFulfilled , onRejected )

So the above could be rewritten as:

return devuelvePromesa1(arg1)
  .then((res_prom1)=>{
          return devuelvePromesa2(res_prom1);
        }, 
        (err_prom1)=> {
          console.error('falló la promesa 1', err_prom1);
          throw err_prom1;
        })
  .then((res_prom2)=>{
          return devuelvePromesa3(res_prom2);
        }, (err_prom2)=> {
          console.error('falló la promesa 2', err_prom2);
          throw err_prom2;
        })
  .then((res_prom3)=>{
         return devuelvePromesa4(res_prom3);
        }, (err_prom3)=> {
          console.error('falló la promesa 3', err_prom3);
          throw err_prom3;
       })
  .catch((error)=> {
    console.error(error);
  });

Except for very specific use cases Who would want to bother declaring a rejection handler for each intermediate promise? To be more practical, the use of the second parameter of then , although it is still allowed by the specification, is considered an antipatron:

The .then (success, fail) anti-pattern

  

Almost a sure sign of using promises as glorified callbacks. Instead   of doThat(function(err, success)) you do doThat().then(success, err)   and rationalize to yourself that at least the code is "less coupled"   or something.

     

The% co_of% signature is mostly about interop, there is almost never a   reason to use% co_of% in application code.

    
answered by 20.09.2018 / 01:03
source