Skip to content

Commit d0bff29

Browse files
andrew8erbryanmacfarlane
authored andcommitted
Return 'null' on status 404 (#57)
* Add a null type to IRestResponse.result since it might be null * Improve initialization of default result object - Use const qualifiers - Initialize 'result' attribute with 'null', so the code matches the documentation - Use strict identity check for 'null' in test * Adjust rest tests * Rename variable in RestClient._processResponse()
1 parent 56c385c commit d0bff29

File tree

2 files changed

+59
-56
lines changed

2 files changed

+59
-56
lines changed

lib/RestClient.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import util = require("./Util");
99

1010
export interface IRestResponse<T> {
1111
statusCode: number,
12-
result: T
12+
result: T | null
1313
}
1414

1515
export interface IRequestOptions {
@@ -174,13 +174,16 @@ export class RestClient {
174174

175175
private async _processResponse<T>(res: httpm.HttpClientResponse, options: IRequestOptions): Promise<IRestResponse<T>> {
176176
return new Promise<IRestResponse<T>>(async (resolve, reject) => {
177-
let rres: IRestResponse<T> = <IRestResponse<T>>{};
178-
let statusCode: number = res.message.statusCode;
179-
rres.statusCode = statusCode;
177+
const statusCode: number = res.message.statusCode;
178+
179+
const response: IRestResponse<T> = {
180+
statusCode: statusCode,
181+
result: null,
182+
};
180183

181184
// not found leads to null obj returned
182185
if (statusCode == httpm.HttpCodes.NotFound) {
183-
resolve(rres);
186+
resolve(response);
184187
}
185188

186189
let obj: any;
@@ -191,10 +194,10 @@ export class RestClient {
191194
if (contents && contents.length > 0) {
192195
obj = JSON.parse(contents);
193196
if (options && options.responseProcessor) {
194-
rres.result = options.responseProcessor(obj);
197+
response.result = options.responseProcessor(obj);
195198
}
196199
else {
197-
rres.result = obj;
200+
response.result = obj;
198201
}
199202
}
200203
}
@@ -217,13 +220,13 @@ export class RestClient {
217220

218221
// attach statusCode and body obj (if available) to the error object
219222
err['statusCode'] = statusCode;
220-
if (rres.result) {
221-
err['result'] = rres.result;
223+
if (response.result) {
224+
err['result'] = response.result;
222225
}
223226

224227
reject(err);
225228
} else {
226-
resolve(rres);
229+
resolve(response);
227230
}
228231
});
229232
}

test/resttests.ts

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ describe('Rest Tests', function () {
2828

2929
it('constructs', () => {
3030
this.timeout(1000);
31-
31+
3232
let rest: restm.RestClient = new restm.RestClient('typed-test-client-tests');
3333
assert(rest, 'rest client should not be null');
3434
})
@@ -38,77 +38,77 @@ describe('Rest Tests', function () {
3838

3939
let restRes: restm.IRestResponse<HttpBinData> = await _rest.get<HttpBinData>('https://httpbin.org/get');
4040
assert(restRes.statusCode == 200, "statusCode should be 200");
41-
assert(restRes.result.url === 'https://httpbin.org/get');
41+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/get');
4242
});
4343

4444
it('gets a resource with baseUrl', async() => {
4545
let restRes: restm.IRestResponse<HttpBinData> = await _restBin.get<HttpBinData>('get');
4646
assert(restRes.statusCode == 200, "statusCode should be 200");
47-
assert(restRes.result.url === 'https://httpbin.org/get');
47+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/get');
4848
});
49-
49+
5050
it('creates a resource', async() => {
5151
let res: any = { name: 'foo' };
5252
let restRes: restm.IRestResponse<HttpBinData> = await _rest.create<HttpBinData>('https://httpbin.org/post', res);
5353
assert(restRes.statusCode == 200, "statusCode should be 200");
54-
assert(restRes.result.url === 'https://httpbin.org/post');
55-
assert(restRes.result.json.name === 'foo');
54+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/post');
55+
assert(restRes.result && restRes.result.json.name === 'foo');
5656
});
57-
57+
5858
it('creates a resource with a baseUrl', async() => {
5959
let res: any = { name: 'foo' };
6060
let restRes: restm.IRestResponse<HttpBinData> = await _restBin.create<HttpBinData>('post', res);
6161
assert(restRes.statusCode == 200, "statusCode should be 200");
62-
assert(restRes.result.url === 'https://httpbin.org/post');
63-
assert(restRes.result.json.name === 'foo');
64-
});
65-
62+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/post');
63+
assert(restRes.result && restRes.result.json.name === 'foo');
64+
});
65+
6666
it('replaces a resource', async() => {
6767
this.timeout(3000);
6868

6969
let res: any = { name: 'foo' };
7070
let restRes: restm.IRestResponse<HttpBinData> = await _rest.replace<HttpBinData>('https://httpbin.org/put', res);
7171
assert(restRes.statusCode == 200, "statusCode should be 200");
72-
assert(restRes.result.url === 'https://httpbin.org/put');
73-
assert(restRes.result.json.name === 'foo');
72+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/put');
73+
assert(restRes.result && restRes.result.json.name === 'foo');
7474
});
75-
75+
7676
it('replaces a resource with a baseUrl', async() => {
7777
let res: any = { name: 'foo' };
7878
let restRes: restm.IRestResponse<HttpBinData> = await _restBin.replace<HttpBinData>('put', res);
7979
assert(restRes.statusCode == 200, "statusCode should be 200");
80-
assert(restRes.result.url === 'https://httpbin.org/put');
81-
assert(restRes.result.json.name === 'foo');
80+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/put');
81+
assert(restRes.result && restRes.result.json.name === 'foo');
8282
});
83-
83+
8484
it('updates a resource', async() => {
8585
let res: any = { name: 'foo' };
8686
let restRes: restm.IRestResponse<HttpBinData> = await _rest.update<HttpBinData>('https://httpbin.org/patch', res);
8787
assert(restRes.statusCode == 200, "statusCode should be 200");
88-
assert(restRes.result.url === 'https://httpbin.org/patch');
89-
assert(restRes.result.json.name === 'foo');
88+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/patch');
89+
assert(restRes.result && restRes.result.json.name === 'foo');
9090
});
91-
91+
9292
it('updates a resource with a baseUrl', async() => {
9393
let res: any = { name: 'foo' };
9494
let restRes: restm.IRestResponse<HttpBinData> = await _restBin.update<HttpBinData>('patch', res);
9595
assert(restRes.statusCode == 200, "statusCode should be 200");
96-
assert(restRes.result.url === 'https://httpbin.org/patch');
97-
assert(restRes.result.json.name === 'foo');
98-
});
96+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/patch');
97+
assert(restRes.result && restRes.result.json.name === 'foo');
98+
});
9999

100100
it('deletes a resource', async() => {
101101
let restRes: restm.IRestResponse<HttpBinData> = await _rest.del<HttpBinData>('https://httpbin.org/delete');
102102
assert(restRes.statusCode == 200, "statusCode should be 200");
103-
assert(restRes.result.url === 'https://httpbin.org/delete');
103+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/delete');
104104
});
105105

106106
it('deletes a resource with a baseUrl', async() => {
107107
let restRes: restm.IRestResponse<HttpBinData> = await _restBin.del<HttpBinData>('delete');
108108
assert(restRes.statusCode == 200, "statusCode should be 200");
109-
assert(restRes.result.url === 'https://httpbin.org/delete');
110-
});
111-
109+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/delete');
110+
});
111+
112112
it('does an options request', async() => {
113113
let restRes: restm.IRestResponse<HttpBinData> = await _rest.options<HttpBinData>('https://httpbin.org');
114114
assert(restRes.statusCode == 200, "statusCode should be 200");
@@ -117,7 +117,7 @@ describe('Rest Tests', function () {
117117
it('does an options request with baseUrl', async() => {
118118
let restRes: restm.IRestResponse<HttpBinData> = await _restBin.options<HttpBinData>('');
119119
assert(restRes.statusCode == 200, "statusCode should be 200");
120-
});
120+
});
121121

122122
//----------------------------------------------
123123
// Get Error Cases
@@ -132,9 +132,9 @@ describe('Rest Tests', function () {
132132

133133
try {
134134
let restRes: restm.IRestResponse<HttpBinData> = await _rest.get<HttpBinData>('https://httpbin.org/status/404');
135-
135+
136136
assert(restRes.statusCode == 404, "statusCode should be 404");
137-
assert(restRes.result == null, "object should be null");
137+
assert(restRes.result === null, "object should be null");
138138
}
139139
catch(err) {
140140
assert(false, "should not throw");
@@ -145,7 +145,7 @@ describe('Rest Tests', function () {
145145
// Unauthorized (401)
146146
// should throw and attach statusCode to the Error object
147147
// err.message is message proerty of resourceful error object or if not supplied, a generic error message
148-
//
148+
//
149149
it('gets and handles unauthorized (401)', async() => {
150150
try {
151151
let restRes: restm.IRestResponse<HttpBinData> = await _rest.get<HttpBinData>('https://httpbin.org/status/401');
@@ -155,13 +155,13 @@ describe('Rest Tests', function () {
155155
assert(err['statusCode'] == 401, "statusCode should be 401");
156156
assert(err.message && err.message.length > 0, "should have error message");
157157
}
158-
});
159-
158+
});
159+
160160
//
161161
// Internal Server Error
162162
// should throw and attach statusCode to the Error object
163163
// err.message is message proerty of resourceful error object or if not supplied, a generic error message
164-
//
164+
//
165165
it('gets and handles a server error (500)', async() => {
166166
try {
167167
let restRes: restm.IRestResponse<HttpBinData> = await _rest.get<HttpBinData>('https://httpbin.org/status/500');
@@ -187,7 +187,7 @@ describe('Rest Tests', function () {
187187

188188
// Assert
189189
assert(restRes.statusCode == 200, "statusCode should be 200");
190-
assert(restRes.result.url === 'https://httpbin.org/anything/anythingextra');
190+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/anythingextra');
191191
});
192192

193193
it('maintains the path from the base url with no slashes', async() => {
@@ -199,7 +199,7 @@ describe('Rest Tests', function () {
199199

200200
// Assert
201201
assert(restRes.statusCode == 200, "statusCode should be 200");
202-
assert(restRes.result.url === 'https://httpbin.org/anything/anythingextra');
202+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/anythingextra');
203203
});
204204

205205
it('maintains the path from the base url with double slashes', async() => {
@@ -211,7 +211,7 @@ describe('Rest Tests', function () {
211211

212212
// Assert
213213
assert(restRes.statusCode == 200, "statusCode should be 200");
214-
assert(restRes.result.url === 'https://httpbin.org/anything/anythingextra');
214+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/anythingextra');
215215
});
216216

217217
it('maintains the path from the base url with multiple parts', async() => {
@@ -223,7 +223,7 @@ describe('Rest Tests', function () {
223223

224224
// Assert
225225
assert(restRes.statusCode == 200, "statusCode should be 200");
226-
assert(restRes.result.url === 'https://httpbin.org/anything/extrapart/anythingextra');
226+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/extrapart/anythingextra');
227227
});
228228

229229
it('maintains the path from the base url where request has multiple parts', async() => {
@@ -235,7 +235,7 @@ describe('Rest Tests', function () {
235235

236236
// Assert
237237
assert(restRes.statusCode == 200, "statusCode should be 200");
238-
assert(restRes.result.url === 'https://httpbin.org/anything/anythingextra/moreparts');
238+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/anythingextra/moreparts');
239239
});
240240

241241
it('maintains the path from the base url where both have multiple parts', async() => {
@@ -247,7 +247,7 @@ describe('Rest Tests', function () {
247247

248248
// Assert
249249
assert(restRes.statusCode == 200, "statusCode should be 200");
250-
assert(restRes.result.url === 'https://httpbin.org/anything/multiple/anythingextra/moreparts');
250+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/multiple/anythingextra/moreparts');
251251
});
252252

253253
it('maintains the path from the base url where request has query parameters', async() => {
@@ -260,9 +260,9 @@ describe('Rest Tests', function () {
260260

261261
// Assert
262262
assert(restRes.statusCode == 200, "statusCode should be 200");
263-
assert(restRes.result.url === 'https://httpbin.org/anything/multiple/anythingextra/moreparts?foo=bar&baz=top');
264-
assert(restRes.result.args.foo === 'bar');
265-
assert(restRes.result.args.baz === 'top');
263+
assert(restRes.result && restRes.result.url === 'https://httpbin.org/anything/multiple/anythingextra/moreparts?foo=bar&baz=top');
264+
assert(restRes.result && restRes.result.args.foo === 'bar');
265+
assert(restRes.result && restRes.result.args.baz === 'top');
266266
});
267267

268268
//
@@ -277,11 +277,11 @@ describe('Rest Tests', function () {
277277
let res: string = util.getUrl('', 'http://httpbin.org');
278278
assert(res === 'http://httpbin.org', "should be http://httpbin.org");
279279
});
280-
280+
281281
it('resolves a null resource with baseUrl', async() => {
282282
let res: string = util.getUrl(null, 'http://httpbin.org');
283283
assert(res === 'http://httpbin.org', "should be http://httpbin.org");
284-
});
284+
});
285285

286286
it('resolves a full resource and no baseUrl', async() => {
287287
let res: string = util.getUrl('http://httpbin.org/get?x=y&a=b');
@@ -296,7 +296,7 @@ describe('Rest Tests', function () {
296296
it('resolves a relative path resource with host baseUrl', async() => {
297297
let res: string = util.getUrl('get/foo', 'http://httpbin.org');
298298
assert(res === 'http://httpbin.org/get/foo', `should be http://httpbin.org/get/foo but is ${res}`);
299-
});
299+
});
300300

301301
it('resolves a rooted path resource with pathed baseUrl', async() => {
302302
let res: string = util.getUrl('/get/foo', 'http://httpbin.org/bar');

0 commit comments

Comments
 (0)