Webhook retry on failure

How does the webhook retry on failure work? I know that http status >= 300 is considered a failure but my testing never showed failures being retried

Thanks for your reply @charlie! @farruco will jump into the thread soon.
Meanwhile could you please describe what are you seeing? What’s the response if not errors?

@charlie webhook calls should be retried a couple of times unless your webhook responds with an status code above 400. Have you checked the logs for your webhooks in your space?

@farruco I have checked the logs for my webhook in my space and determined that the only time the system retries is if I force my listener to wait more than 30 seconds before responding. If I immediately respond with any 3xx, 4xx or 5xx http status it doesn’t get retried.

Is that expected behavior?

I made a basic node/express app to test this:

var express = require('express')
var bodyParser = require('body-parser')
var app = express()

app.use(bodyParser.json({type: ['application/*+json', 'application/json']}))
app.set('port', (process.env.PORT || 5000))

var count = {}
var http_status = [400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 426, 428, 429, 431, 451, 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511, 300, 301, 302, 303, 304, 305, 306, 307, 308, ]
var c = 0

app.all('/', (request, response) => {
  let name = request.body.fields.name['en-US']
  count[name] = count[name] ? count[name] + 1 : 1
  let status = count[name] < 3 ? http_status[c] : 200
  c = c < http_status.length - 1 ? c + 1 : 0
  console.log(`${new Date()} - Title: "${name}", Count: ${count[name]}, Status: ${status}`)
  response.status(status).end()
})

app.listen(app.get('port'), () => {
  console.log('Node app is running on port', app.get('port'))
})

With this code I don’t get any retries and I see this in my webhook logs:

If I replace the response.status(status).end() with this

if (status !== 200) 
  setTimeout(() => {
    response.status(status).end()
  }, 31000)
else
  response.status(status).end()

so it waits 31 seconds before sending the response (i.e., longer than the 30 second timeout shown in the webhook log detail) , I see the retries happening:

Mon Jul 24 2017 22:18:35 - Title: "2", Count: 1, Status: 400
Mon Jul 24 2017 22:19:35 - Title: "2", Count: 2, Status: 401
Mon Jul 24 2017 22:21:35 - Title: "2", Count: 3, Status: 200

You can see the time between the 1st and 2nd retries is 60 seconds and between the 2nd and 3rd is 120 seconds. But again it only retries on connections which timeout (i.e., last longer than 30 seconds), and not for connections which return a 3xx, 4xx, or 5xx http status code as is suggested in the documentation.

Error handling

Contentful will use the HTTP response status code of the webhook call to decide whether it succeeded or failed:

  • Success: The webhook responded with an HTTP status code < 300.
  • Error: The webhook responded with an HTTP status code >= 300.

In case of an error, the webhook will periodically retry its request with increasing delays up to a maximum of 3 attempts.

So is the documentation wrong or am I missing something?

Thanks Charlie! Inviting @tim to the thread. Tim could you please take a look at it?
Or @farruco?
Thank you.

I tried again using only 5xx responses and Contentful did retry those responses. So it seems Contentful retries when it it gets a 5xx response, but not for 4xx or 3xx responses. Are the docs wrong or is this a Contentful bug?

1 Like

Hi.
I’m having the same kind of situation. If the API returns a 500, I don’t see Contentful doing a retry. Is there a setting I must enable in the webhook first?