Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Axios calling request setHeader with function as value #5055

Open
KrayzeeKev opened this issue Oct 7, 2022 · 6 comments
Open

Axios calling request setHeader with function as value #5055

KrayzeeKev opened this issue Oct 7, 2022 · 6 comments

Comments

@KrayzeeKev
Copy link

KrayzeeKev commented Oct 7, 2022

Describe the bug

Axios is calling request.setHeader with a function as the value and this is causing nock to throw an error. I see nothing in the NodeJS documentation saying that a function is a valid value for a header (I was guessing perhaps you could provide a function it would call but there is nothing in the docs to suggest that). As such, I'm starting with this as an Axios bug and not a deficiency in nock's implementation of Request.

It seems this is triggered by using axios-retry.

If, however, passing a function to request.setHeader is a valid thing, I'll close this and raise something on nock.

The function being passed to request.setHeader is the "get" method in the AxiosHeaders prototype.

function(header, parser) {
    header = normalizeHeader(header);
    if (!header) return undefined;
    const key = findKey(this, header);
    if (key) {
      const value = this[key];
      if (!parser) {
        return value;
      }
      if (parser === true) {
        return parseTokens(value);
      }
      if (utils.isFunction(parser)) {
        return parser.call(this, value, key);
      }
      if (utils.isRegExp(parser)) {
        return parser.exec(value);
      }
      throw new TypeError('parser must be boolean|regexp|function');
    }
  }

The error returned by nock's request.setHeader is: TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["0"]

To Reproduce

'use strict';

const nock = require('nock');
const axios = require('axios');
const axiosRetry = require('axios-retry');

nock('http://localhost')
  .get('/')
    .times(2)
    .query(true)
    .delay(10000)
    .reply(200, [])
  .get('/')
    .reply(200, []);


const ax = axios.create();
let retryCount = 0;
axiosRetry(ax, {
  retries: 3,
  shouldResetTimeout: true,
  retryCondition: err => {
    if (err.code === 'ECONNABORTED' || axiosRetry.isNetworkOrIdempotentRequestError(err) ) {
      console.warn(`Timeout - RETRY ${++retryCount}`);
      return true;
    }
    return false;
  },
});

ax( {
  url: 'http://localhost',
  method: 'GET',
  timeout: 1000
}).then(resp => console.log(resp.data));

Expected behavior

It should get a timeout error twice and then receive and log an empty array.

Environment

  • Axios Version 1.1.0
  • Node.js Version 18.7
  • Additional Library Versions axios-retry 3.3.1, nock 13.2.9
@chrno1209
Copy link

I am having the same issue, had to do a work around by removing all invalid headers (using interceptor) before sending request.

@grenik
Copy link

grenik commented Oct 11, 2022

Seems relevant to #5089 which shall be fixed in #5090

@KrayzeeKev
Copy link
Author

@grenik Apparently, #5090 is done and merged. Or replaced with #5162. NOT FIXED. #5162 is merged and current v1.x branch has the same fault.

@DigitalBrainJS
Copy link
Collaborator

DigitalBrainJS commented Nov 4, 2022

On Axios v0.27.2 that code logs:

Timeout - RETRY 1
Timeout - RETRY 2
Timeout - RETRY 3

node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^
AxiosError: Nock: No match for request {
  "method": "GET",
  "url": "http://localhost/",
  "headers": {
    "accept": "application/json, text/plain, */*",
    "user-agent": "axios/0.27.2" // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  }
}

On Axios v1.1.3 with PR #5224

Timeout - RETRY 1
Timeout - RETRY 2
Timeout - RETRY 3

file:///H:/JS/forks/axios/lib/core/AxiosError.js:89
  AxiosError.call(axiosError, error.message, code, config, request, response);
             ^
AxiosError: Nock: No match for request {
  "method": "GET",
  "url": "http://localhost/",
  "headers": {
    "accept": "application/json, text/plain, */*",
    "user-agent": "axios/1.1.3", // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    "accept-encoding": "gzip, deflate, br"
  }
}

It's hard to tell whether the issue is covered by the PR if the error is not reproducible on v0.27.2, but Axios will support an AxiosHeader instance as the headers config.

@KrayzeeKev
Copy link
Author

@DigitalBrainJS I'm sorry. I had removed an actual URL in favour of a fake one so the successful call at the end never happened. Added another .get to the nock call above.
I also removed the .default from the axios require which was legal in the early 1.x releases still, I think but has become illegal now. There's a PR for the next release that puts it back. But it does nothing.
Code above should now behave as advertised.

@KrayzeeKev
Copy link
Author

@DigitalBrainJS Any chance of having a look at this with the revision I made?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants