Skip to content
This repository has been archived by the owner on Feb 13, 2024. It is now read-only.

Improve Retry Behaviour. #146

Merged
merged 1 commit into from
Jan 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const assert = require('assert')
const removeSlash = require('remove-trailing-slash')
const validate = require('@segment/loosely-validate-event')
const axios = require('axios')
const retries = require('axios-retry')
const axiosRetry = require('axios-retry')
const ms = require('ms')
const uid = require('crypto-token')
const version = require('./package.json').version
Expand Down Expand Up @@ -38,7 +38,10 @@ class Analytics {
this.flushInterval = options.flushInterval || 10000
this.flushed = false

retries(axios, options.retryCount || 3)
axiosRetry(axios, {
retries: options.retryCount || 3,
retryCondition: this._isErrorRetryable
})
}

/**
Expand Down Expand Up @@ -247,6 +250,30 @@ class Analytics {
done(err)
})
}

_isErrorRetryable (error) {
// Retry Network Errors.
if (axiosRetry.isNetworkError(error)) {
return true
}

if (!error.response) {
// Cannot determine if the request can be retried
return false
}

// Retry Server Errors (5xx).
if (error.response.status >= 500 && error.response.status <= 599) {
return true
}

// Retry if rate limited.
if (error.response.status === 429) {
return true
}

return false
}
}

module.exports = Analytics
17 changes: 17 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,23 @@ test('alias - require previousId and userId', t => {
})
})

test('isErrorRetryable', t => {
const client = createClient()

t.false(client._isErrorRetryable({}))

// ETIMEDOUT is retryable as per `is-retry-allowed` (used by axios-retry in `isNetworkError`).
t.true(client._isErrorRetryable({ code: 'ETIMEDOUT' }))

// ECONNABORTED is not retryable as per `is-retry-allowed` (used by axios-retry in `isNetworkError`).
t.false(client._isErrorRetryable({ code: 'ECONNABORTED' }))

t.true(client._isErrorRetryable({ response: { status: 500 } }))
t.true(client._isErrorRetryable({ response: { status: 429 } }))

t.false(client._isErrorRetryable({ response: { status: 200 } }))
})

const { RUN_E2E_TESTS } = process.env

if (RUN_E2E_TESTS) {
Expand Down