got: Why this "The `body`, `json` and `form` options are mutually exclusive" error?

What would you like to discuss?

I am upgrading my (functional) code from the latest got@10.x.X to got@11.0.1.

Went through the release notes, updated GotError and .pagination… Typescript compiles ok but code breaks.

Not really sure why but I failed at catching any exception occurring within got so I resorted to vscode debugger.

The first got call fails with this sequence sequence:

  1. call got to query for some CRM data as json
  • GET method
  • a json payload defining the filter
  • allowGetBody: true
  • an afterResponse hook to acquire/refresh oauth token (using got with a POST method with a json payload)
  1. since there is no initial oauth token, the afterResponse hook is executed:
    afterResponse: [
      async (response, retryWithMergedOptions) => {
        // Unauthorized
        if (response.statusCode === 401) {
          const updatedOptions: ExtendOptions = { headers: { 'oauth-token': await getNewAuthToken() } };

          // Save for further requests
          authenticatedInstance.defaults.options = got.mergeOptions(
            authenticatedInstance.defaults.options,
            updatedOptions
          );

          return retryWithMergedOptions(updatedOptions);
        }

        // No changes otherwise
        return response;
      },
    ],

The oauth token is correctly acquired/renewed, object updatedOptions is correct but retryWithMergedOptions(updatedOptions) fails with throw new TypeError('The body, jsonandform options are mutually exclusive') At this point of _finalizeBody(), this.option holds my json filter in both body and json property.

I am unsure if I originally made a mistake somewhere in the past and must feel lucky my code works in got@10.x.x or if I happen to hit e regression.

Please advise.

Checklist

  • I have read the documentation.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 19 (7 by maintainers)

Most upvoted comments

It doesn’t throw because the error handler is executed only once (as expected). It should raise an uncaught exception error, but it doesn’t because there’s another error handler attached to the PromisableRequest instance. I don’t know why there’s a second handler, but I’m looking at it rn.

@szmarczak So this is indeed the original problem I identified using the vscode debugger, and it confirms I was unable to catch any thrown error/exception…

The above test doesn’t fully reproduce my original issue (TypeError instead of a timeout) As I was putting up a test case of my own code I ended being stuck by that timeout. My real case is slightly more advanced/complex. I will complete it when there is no longer a timeout (which may share the same root cause as my original issue.)

@szmarczak FYI I am trying to reproduce & isolate my case. Sharing current code is not a practical options for it would imply divulging some business information beyond my scope of decision 😉

So far it seems that:

  • If I first get a valid oauth token and provide it to the got instance before querying, this partly solves the issue (by obviously avoiding going through the .afterResponse () hook)
  • If I change my queries from got(url, {json: awesome}) to got(url, {body: JSON.stringify(awesome)}) it seems to fix the issue.
  • There are still some of the above TypeError occurring, when using the ‘.paginate()’ method, but I am still investigating this.