api.get(...).then(...).catch(...).finally is not a function

Only a native Promise (constructed with new Promise) is guaranteed to have a .finally method (in newer environments). (in older environments, .finally won't work at all with Promises created with new Promise)

It looks like axios doesn't use new Promise internally - rather, it just returns a thenable, which is not guaranteed to have a finally method (and because it doesn't, it throws an error).

While you could use the explicit Promise construction antipattern to wrap the axios call in a native new Promise, so that it has Promise.prototype.finally in its prototype chain, a better option (thanks Bergi!) is to just use Promise.resolve, which will turn a thenable into a native Promise while preserving the failure or success of the thenable:

get(API, params = this.defaultParams) {
  this.call = "GET";
  let constructedURL = this.constructURL(API, params);
  axiosRetry(axios, { retries: this.retry });
  return Promise.resolve(axios.get(constructedURL, this.config));
}

The promise should be taking finally of es6, which I am not sure is something that gets supported by the axios promise, if I may, I sugest use then instead of finally

import API from "../../utils/API";

componentDidMount() {
let merchantId = this.props.merchant.id;
let api = new API(this.props.gatheredTokens);
let self = this;
api.setRetry(10);
api
  .get("merchantMessages", { repl_str: merchantId })
  .then(response => this.merchantMessageConfiguration(response.data))
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    self.state.list.push(
      <Card
        merchant={self.props.merchant}
        key={self.props.merchant.id}
        bubblemsg={self.state.bubblemsg}
      />
    );
  })
  .then(function () {
    self.merchantNoticeLoading(self);
  });
 }

You can use a npm package promise.prototype.finally for polyfill.

doing like this:

var promiseFinally = require('promise.prototype.finally');
promiseFinally.shim();

or in TypeScript:

//@ts-expect-error
import promiseFinally from 'promise.prototype.finally';

promiseFinally.shim();

The package will override the function if Promise.prototype.finally is not found in user browser. And if the browser support Promise.prototype.finally, it will just use the native function.

I use Create React App for building frontend project. It seems that Babel and TypeScript won't manage with this tough things, you should deal with it on your own.


I suggest to use another then instead of using finally. then after catch is works like a finally. don't forget to use at least one catch in your promise chain, in order to handle your instructions failure.

So this two line of code is the same:

api.get(…).then(…).catch(…).then(...)

and

api.get(…).then(…).catch(…).finally(...)