0

I am working on a project that always catch rejected promise, turns it into resolved one with error code, like this

return new Promise((resolve, reject) => {
        axios({
          ...
        }).then(res => {
            resolve(res);
        }).catch(err => {
            let res = { ... }
            res.error = err
            resolve(res)
        })
    })

Then whenever call this api, rejected case is handled like this, i.e. without catch

   axios_call(...).then(res => {
        if (!res.err) {
            //resolve case
        } else {
            //reject case
        }
    })

I never handle the rejected promise like this before so I am not sure will it cause any problem or it is just a different code style and works fine too.

I checked the possible duplicated q/a What is the explicit promise construction antipattern and how do I avoid it? But I believed they are not the same. Because my question is about handling the rejected promise while that question is about deferred object, e.g. errors and rejections are not swallowed in my case.

Qiulang
  • 10,295
  • 11
  • 80
  • 129
  • Possible duplicate of [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – CertainPerformance Jan 18 '19 at 10:16
  • Hi I checked possible duplicated one but I don't think mine is duplicated, for starters, deferred object may swallow errors and rejections but my question is exactly about how to handle the rejections. – Qiulang Jan 18 '19 at 10:29
  • You're already handling the rejections with `catch` - all you need to do is drop the `new Promise` explicit construction, eg `return axios(....).catch((err) => ({ ..., err }));` – CertainPerformance Jan 18 '19 at 19:51
  • @CertainPerformance my question is not duplicated with the one you said, don't you agree ? new promise is unnecessary but my question is more about handling rejected promise. – Qiulang Jan 20 '19 at 03:27

1 Answers1

1

First of all, avoid the Promise constructor antipattern! Your axios_call code should better look simply like this:

return axios({
    ...
}).catch(err => {
    return { ..., error: err };
});

Then whenever call this api, rejected case is handled without catch. I never had handled the rejected promise like this before so I am not sure will it cause any problem or it is just a different code style and works fine too.

It works, but it's not fine. This style of error handling is weird and really non-idiomatic. It has the same problems as the traditional node-style callback API with separate error and result parameters:

  • the promise can't know whether you handled the error or not. You will not get any unhandled rejection warnings.
  • you always must write the code to deal with the res.error, if you want it or not. With normal promise usage, you could just supply separate onFulfill and onReject callbacks, and omitting the latter will get you the sensible default behaviour of forwarding the error instead of just dropping it.

I cannot see any advantages that your style would present, so I would recommend to avoid it and use normal promise rejections.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Hi, I know this was a rather old question but recently I use Fetch api a lot and its usage gives me a similar feeling, to [quote](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#differences_from_jquery.ajax) "The promise returned from fetch() won't reject on HTTP errors even if the response is an HTTP 404 or 500. Instead, as soon as the server responds with headers, the promise will resolve (with the ok property of the response set to false if the response isn't in the range 200–299). " So I always need to check `res.ok` to know if I get a valid response. – Qiulang Jul 14 '23 at 08:08
  • 1
    @Qiulang Yes, the fetch api design is a bit strange. It's a reasonable design, since the `fetch()` promise still *does* reject (on network/connection errors), unlike the OP's `axios_call` which *never* rejects. The fetch api design is perfect to represent these multi-layered failure modes. And yet, it is not userfriendly and quite error-prone, as soooo many people make the [mistake of not checking `response.ok`](http://blog.niftysnippets.org/2018/06/common-fetch-errors.html). They really should have provided a second function that rejects with http status errors. – Bergi Jul 14 '23 at 15:01
  • It was me that aksed the OP. lol – Qiulang Jul 14 '23 at 15:15
  • @Qiulang oh right :-D – Bergi Jul 14 '23 at 15:45