0

i've some doubt on promise:

this is my api functions using axios:

const _get = (url: string) => axios
.get(url)
.then((response: { data: responseData }) => {
 if (response) {
   console.log(response)
    const { data, status, message } = response.data;
    if (status) {
      return data
    } else {
      throw new Error(message);
    }
  } 
})
 //notification is an antd component to show a toast with the error
.catch((error: Error) => notification.error({ message: 'Error', description: error.message }));


export const doStuff = (id: number) =>_get('/api/do/${id}');

When i call the api in case of error the then() is called

  const callDoStuff = (id: number) => {
    doStuff(id).then(() => {
      //called also if doStuff catch() is resolved
      notification.success({ message: 'Success', description: 'Template deleted!' });
    });
  };

so in catch block if i return something is considered resolved and so the outer function then() is called? in this case the only way is to keep the propagation of the error throwing an exception in the catch?

Thanks


possible soulution:

const _get = (url: string) => axios
.get(url)
.then((response: { data: responseData }) => {
 if (response) {
   console.log(response)
    const { data, status, message } = response.data;
    if (status) {
      return data
    } else {
      throw new Error(message); 
    }
  } 
})

using specific catcher for then() error

const callDoStuff = (id: number) => {
doStuff(id)
.then((response) => {// success handler}, e=>{// specific error thrown by the inner then })})
.catch(e=>{//axios error })

using generic catcher for errors

const callDoStuff = (id: number) => {
  doStuff(id)
  .then((response) => { //success handler })
  .catch(e=>{ // generic error handler })
claud.io
  • 1,523
  • 3
  • 15
  • 30

1 Answers1

2

so in catch block if i return something is considered resolved and so the outer function then() is called?

Yes.

in this case the only way is to keep the propagation of the error throwing an exception in the catch?

I would suggest not to put the .catch() inside _get. Instead, write

function callDoStuff(id: number) {
  doStuff(id).then(() => {
    notification.success({ message: 'Success', description: 'Template deleted!' });
  }, (error: Error) => {
    notification.error({ message: 'Error', description: error.message })
  });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Ty for the fast replay, so: (error: Error) => { notification.error({ message: 'Error', description: error.message }) } will be used as reject handle in the _get function then? is the same of doing doStuff(id).then(() => { notification.success({ message: 'Success', description: 'Template deleted!' }); }).catch( (error: Error) => { notification.error({ message: 'Error', description: error.message }) }); right? – claud.io Dec 02 '20 at 11:26
  • if i want to handle error in a generic way is it wrong to handle errors in my way? – claud.io Dec 02 '20 at 11:27
  • Not sure what you mean by "*will be used as reject handle in the _get function*". The `_get` function does know nothing about handles, it just rejects the promise it had returned. "*Are `.then(…, …)` and `.then(…).catch(…)` equivalent?*" - [not exactly](https://stackoverflow.com/q/24662289/1048572). – Bergi Dec 02 '20 at 11:29
  • "*is it wrong to handle errors in my way?*" - if you refer to putting `.catch()` inside the `_get` function, yes that's wrong, as it observably doesn't work like you want. If you want to use the same error handling function everywhere, just make it a named function that you can share. – Bergi Dec 02 '20 at 11:31
  • i'm a little confused, .then(…, …) in this case the error callback will only catch the reject in the _get.then() correct? so this way i have to duplicate my code, instead, if i put a catch in the _get() then the catch() block will catch also the error thrown by the then block no? – claud.io Dec 02 '20 at 11:42
  • i've updated the question with a possible solution to be more clear – claud.io Dec 02 '20 at 11:48
  • `then(…, …)` is close to `.then(…).catch(…)` if the fulfillment callback doesn't throw an exception. Both are absolutely different from `.catch(…).then(…)`. – Bergi Dec 02 '20 at 11:51
  • Putting a `.catch(err => { /* ignore */ });` at the end of every chain does not look like a good solution to me. Really, if you need to re-throw the error, that's a sign you're trying to handle it in the wrong place. – Bergi Dec 02 '20 at 11:52
  • thanks for your time, i think i got it, please check the update to my question to see if now i've understand – claud.io Dec 02 '20 at 12:02
  • No, in the "*using specific catcher*" snippet you named the error handlers exactly the wrong way round. Please see [this post](https://stackoverflow.com/q/24662289/1048572) for more elaboration. – Bergi Dec 02 '20 at 12:58
  • i've red your answer to the post, but i don't understand why "using specific catcher" is wrong if for some reason i need specific both a generic handler (used for example if the response return a 500) and a specific one (for example if the status returned from the response is a specific status) – claud.io Dec 02 '20 at 14:33
  • I'm not saying it doesn't work, I'm saying the comments "*`// specific error thrown by the inner then`*" and "*`//axios error`*" are wrong. Either way, I would suggest distinguishing different kinds of errors in the same handler (with an `if` cascade), not chained handlers. But unless you're more specific about what errors are handled how, I cannot advise a particular solution - all my answer says is that the `notification.error()` handling should be done at the same level (in the same function) as the `notification.success()` call. – Bergi Dec 02 '20 at 14:56
  • yes sorry, i think we are saying the same thing, i've just exposed my problem without enough info, thanks – claud.io Dec 02 '20 at 15:03