Skip to content

Commit 2dca4b3

Browse files
authored
Reject promises on 4XX and 5XX responses (#1)
1 parent 54a604a commit 2dca4b3

File tree

7 files changed

+179
-7
lines changed

7 files changed

+179
-7
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ npm-debug.log
33
.env
44
coverage
55
.vscode
6+
.idea
7+

helpers/isErrorResponse.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Checks if the returned response is an error response.
3+
*
4+
* @param response a Node's http.IncomingMessage object
5+
* @return boolean true if the response status is 4XX or 5XX
6+
*/
7+
function isErrorResponse(response) {
8+
return response.statusCode >= 400;
9+
}
10+
11+
module.exports = isErrorResponse;

index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var extend = require('extend');
1111
var when = require('when');
1212
var request = require('request');
1313
var RetryStrategies = require('./strategies');
14+
var isErrorResponse = require('./helpers/isErrorResponse')
1415
var _ = require('lodash');
1516

1617
var DEFAULTS = {
@@ -109,6 +110,10 @@ function Request(url, options, f, retryConfig) {
109110
return this._reject(err);
110111
}
111112

113+
if (isErrorResponse(response)) {
114+
return this._reject(this.fullResponse ? response : body);
115+
}
116+
112117
// resolve with the full response or just the body
113118
response = this.fullResponse ? response : body;
114119
this._resolve(response);

package-lock.json

Lines changed: 105 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "requestretry",
2+
"name": "@hmcts/requestretry",
33
"description": "request-retry wrap nodejs request to retry http(s) requests in case of error",
4-
"version": "1.13.0",
4+
"version": "1.0.0",
55
"author": {
66
"name": "Francois-Guillaume Ribreau",
77
"email": "npm@fgribreau.com",
@@ -18,7 +18,8 @@
1818
}
1919
],
2020
"repository": {
21-
"url": "https://github.com/FGRibreau/node-request-retry"
21+
"type": "git",
22+
"url": "https://github.com/hmcts/node-request-retry"
2223
},
2324
"main": "index.js",
2425
"scripts": {
@@ -55,6 +56,7 @@
5556
"coveralls": "^2.11.12",
5657
"kew": "~0.7.0",
5758
"mocha": "^3.0.2",
59+
"nock": "^9.2.3",
5860
"nyc": "^10.0.0",
5961
"q": "~1.4.1",
6062
"rsvp": "^3.2.1",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
3+
const isErrorResponse = require('../../helpers/isErrorResponse');
4+
const expect = require('chai').expect;
5+
6+
describe('isErrorResponse', function () {
7+
[200, 201, 302].forEach(statusCode => {
8+
it(`should return false for ${statusCode} statusCode`, function () {
9+
expect(isErrorResponse({ statusCode: statusCode })).to.equal(false);
10+
});
11+
});
12+
13+
[400, 401, 403, 422, 500, 502].forEach(statusCode => {
14+
it(`should return true for ${statusCode} statusCode`, function () {
15+
expect(isErrorResponse({ statusCode: statusCode })).to.equal(true);
16+
});
17+
});
18+
});

test/promises.test.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
var request = require('../');
44
var t = require('chai').assert;
5+
var nock = require('nock')
56

67
describe('Promises support', function () {
78

@@ -84,6 +85,38 @@ describe('Promises support', function () {
8485
});
8586
});
8687

88+
it('should reject the promise on 400 response', function (done) {
89+
nock('http://some-test-host')
90+
.get('/return-400')
91+
.reply(400, 'Client Error');
92+
93+
request({
94+
url: 'http://some-test-host/return-400',
95+
maxAttempts: 1,
96+
retryStrategy: request.RetryStrategies.HTTPOrNetworkError
97+
})
98+
.catch(function (err) {
99+
t.strictEqual(err.body, 'Client Error');
100+
done();
101+
});
102+
});
103+
104+
it('should reject the promise on 500 response', function (done) {
105+
nock('http://some-test-host')
106+
.get('/return-500')
107+
.reply(500, 'Server Error');
108+
109+
request({
110+
url: 'http://some-test-host/return-500',
111+
maxAttempts: 1,
112+
retryStrategy: request.RetryStrategies.HTTPOrNetworkError
113+
})
114+
.catch(function (err) {
115+
t.strictEqual(err.body, 'Server Error');
116+
done();
117+
});
118+
});
119+
87120
it('should still work with callbacks', function (done) {
88121
request({url: 'http://www.filltext.com/?rows=1'}, function requestCallback(err, response, body) {
89122
t.strictEqual(response.statusCode, 200);
@@ -108,10 +141,6 @@ describe('Promises support', function () {
108141
promiseFactory: promiseFactoryFn // custom promise factory function
109142
})
110143
.then(function (body) {
111-
if (throwError) {
112-
throw body; // To simulate an error in the request
113-
}
114-
115144
t.isString(body);
116145
var data = JSON.parse(body);
117146
t.isArray(data);

0 commit comments

Comments
 (0)