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

How to access headers on 429 Responses? #345

Closed
abmagil opened this issue Oct 9, 2019 · 5 comments
Closed

How to access headers on 429 Responses? #345

abmagil opened this issue Oct 9, 2019 · 5 comments

Comments

@abmagil
Copy link

abmagil commented Oct 9, 2019

Expected Behavior

On error, with retryOnError set to false, when I hit the rate limit, I would expect to receive an error that exposes the rate-limit metadata referenced here.

Actual Behavior

The error that is sent back is a JS error with string fields that do not include the headers that offer the metadata about how long to wait.

{
  "status": 429,
  "statusText": "Too Many Requests",
  "message": "You have exceeded the rate limit of the Organization this Space belongs to by making too many API requests within a short timespan. Please wait a moment before trying the request again.",
  "details": {},
  "request": {
    "url": "<ENTRY URL>",
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/vnd.contentful.management.v1+json",
      "X-Contentful-User-Agent": "sdk contentful-management.js/5.2.1; platform node.js/v10.15.3; os Windows/10.0.17134;",
      "Authorization": "Bearer ...i0Qlc",
      "user-agent": "node.js/v10.15.3",
      "Accept-Encoding": "gzip",
      "X-Contentful-Version": 65,
      "Content-Length": 427
    },
    "method": "put",
    "payloadData": "<ENTRY DATA>"
  },
  "requestId": ""
}

Possible Solution

include a javascript object within the caught error that exposes the X-Contentful-RateLimit-Hour-Limit, X-Contentful-RateLimit-Hour-Remaining, X-Contentful-RateLimit-Reset, X-Contentful-RateLimit-Second-Limit, X-Contentful-RateLimit-Second-Remaining headers.

Even better might be to allow me to provide my own Axios client that I could configure myself, which would give me access to the catch behavior directly.

Steps to Reproduce

  1. Create a Management Environment client with retryOnError set to false
const client = contentfulManagement.createClient({ accessToken: this.config.CONTENT_MANAGEMENT_TOKEN, retryOnError: false });
const space = await client.getSpace(this.spaceId);
const updateEnvironment = await space.getEnvironment(this.environmentId);
  1. Using this environment client, exceed the rate limit.
while(true) {
    try {
        await updateEnvironment.getEntry(entryId)
    } catch (err) {
        console.log(err) // this is where I would like access to rate-limit response headers, but don't have it
    }
}

Context

We need to post back to Contentful with an evergreen timestamp in the payload for validation logic which we do on our own. Because we didn't have access to the payload using retryOnError: true, we needed to roll our own retry logic. Unfortunately, we then encountered this behavior, which prevents us from rate limiting on our side.

Environment

  • Package Version: "contentful": "7.7.0", "contentful-management": "5.8.0",

  • Which API are you using?: Management

@Khaledgarbaya
Copy link
Contributor

Hi @abmagil,
You can pass a handler to be called every time you receive a rate limit error and there you will get the headers you need.

const client = contentfulManagement.createClient({ accessToken: this.config.CONTENT_MANAGEMENT_TOKEN, retryOnError: false, logHandler: (loglevel, data)=>{} });

@abmagil
Copy link
Author

abmagil commented Oct 10, 2019

Hi @Khaledgarbaya - I updated my code to be

const logHandler= (loglevel: any, data: any) => { 
                console.log(loglevel);
                console.log(data);
            };
            // We should delete this hard-coded token and delete it from Contentful.
            const client = contentfulManagement.createClient({ accessToken: this.config.CONTENT_MANAGEMENT_TOKEN, retryOnError: false, logHandler});

and re-ran my calls. I saw many Rate limit error occurred. Waiting for 1641 ms before retrying... errors in my console, but never any logLevel or error data logging. I set a breakpoint in this code and it didn't hit either.

Is there a missing step in your solution? I don't seem to ever hit that code.

@n-eit
Copy link

n-eit commented Mar 22, 2023

Hello.
Any update concerning that issue? I do have the same behaviour, using either responseLogger, requestLogger or logHandler.

@mayakarabula
Copy link
Member

closing the issue, if you still need help with this please reach out to Contentful support

@votemike
Copy link

votemike commented Mar 7, 2024

@n-eit
I have been battling this the last few days.
I found that on a successful response I could access response.headers['x-contentful-ratelimit-reset'], but in the case of a 429, that is wrapped in an extra layer of response and so you have to access response.response.headers['x-contentful-ratelimit-reset']

const client = contentful.createClient({
  accessToken: '<my-token>',
  responseLogger: async (response) => {
      if (response.headers) {
          console.log(new Date().getTime() / 1000, response.headers['x-contentful-ratelimit-reset'], response.headers['x-contentful-ratelimit-second-limit'], response.headers['x-contentful-ratelimit-second-remaining']);
      } else {
          console.log(new Date().getTime() / 1000, response.response.headers['x-contentful-ratelimit-reset'], response.response.headers['x-contentful-ratelimit-second-limit'], response.response.headers['x-contentful-ratelimit-second-remaining']);
      }
  },
});

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

5 participants