-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BUGFIX] ensure handleREsponse always called in rest adapter
- Loading branch information
Showing
4 changed files
with
156 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
packages/-ember-data/tests/unit/utils/determine-body-promise-test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copied from ember-fetch addon | ||
|
||
import { module, test } from 'qunit'; | ||
import { resolve } from 'rsvp'; | ||
import { determineBodyPromise } from '@ember-data/adapter/-private'; | ||
|
||
class Response { | ||
ok = true; | ||
|
||
constructor(text, options) { | ||
this.status = options.status; | ||
this._text = text; | ||
} | ||
|
||
text() { | ||
return resolve(this._text); | ||
} | ||
} | ||
|
||
module('Unit | determineBodyPromise', function() { | ||
test('determineBodyResponse returns the body when it is present', function(assert) { | ||
assert.expect(1); | ||
|
||
const response = new Response('{"data": "foo"}', { status: 200 }); | ||
const bodyPromise = determineBodyPromise(response, {}); | ||
|
||
return bodyPromise.then(body => { | ||
assert.deepEqual(body, { data: 'foo' }); | ||
}); | ||
}); | ||
|
||
test('determineBodyResponse returns the body even if it is not json', function(assert) { | ||
assert.expect(1); | ||
|
||
const response = new Response('this is not json', { status: 200 }); | ||
const bodyPromise = determineBodyPromise(response, {}); | ||
|
||
return bodyPromise.then(body => { | ||
assert.deepEqual(body, 'this is not json'); | ||
}); | ||
}); | ||
|
||
test('determineBodyResponse returns undefined when the http status code is 204', function(assert) { | ||
assert.expect(1); | ||
|
||
const response = new Response(null, { status: 204 }); | ||
const bodyPromise = determineBodyPromise(response, {}); | ||
|
||
return bodyPromise.then(body => { | ||
assert.deepEqual(body, undefined); | ||
}); | ||
}); | ||
|
||
test('determineBodyResponse returns undefined when the http status code is 205', function(assert) { | ||
assert.expect(1); | ||
|
||
const response = new Response(null, { status: 205 }); | ||
const bodyPromise = determineBodyPromise(response, {}); | ||
|
||
return bodyPromise.then(body => { | ||
assert.deepEqual(body, undefined); | ||
}); | ||
}); | ||
|
||
test("determineBodyResponse returns undefined when the request method is 'HEAD'", function(assert) { | ||
assert.expect(1); | ||
|
||
const response = new Response(null, { status: 200 }); | ||
const bodyPromise = determineBodyPromise(response, { method: 'HEAD' }); | ||
|
||
return bodyPromise.then(body => { | ||
assert.deepEqual(body, undefined); | ||
}); | ||
}); | ||
}); |
73 changes: 46 additions & 27 deletions
73
packages/adapter/addon/-private/utils/determine-body-promise.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,60 @@ | ||
import { warn } from '@ember/debug'; | ||
import { DEBUG } from '@glimmer/env'; | ||
import { resolve } from 'rsvp'; | ||
|
||
/* | ||
* Function that always attempts to parse the response as json, and if an error is thrown, | ||
* returns `undefined` if the response is successful and has a status code of 204 (No Content), | ||
* or 205 (Reset Content) or if the request method was 'HEAD', and the plain payload otherwise. | ||
*/ | ||
export function determineBodyPromise( | ||
function _determineBodyPromise( | ||
response: Response, | ||
requestData: JQueryAjaxSettings | ||
requestData: JQueryAjaxSettings, | ||
payload: string | object | undefined | ||
): Promise<object | string | undefined> { | ||
return response.text().then(function(payload) { | ||
let ret: string | object | undefined = payload; | ||
try { | ||
ret = JSON.parse(payload); | ||
} catch (error) { | ||
if (!(error instanceof SyntaxError)) { | ||
throw error; | ||
} | ||
const status = response.status; | ||
if (response.ok && (status === 204 || status === 205 || requestData.method === 'HEAD')) { | ||
ret = undefined; | ||
} else { | ||
if (DEBUG) { | ||
let message = `The server returned an empty string for ${requestData.method} ${requestData.url}, which cannot be parsed into a valid JSON. Return either null or {}.`; | ||
if (payload === '') { | ||
warn(message, true, { | ||
id: 'ds.adapter.returned-empty-string-as-JSON', | ||
}); | ||
throw error; | ||
} | ||
let ret: string | object | undefined = payload; | ||
try { | ||
if (payload === null) { | ||
throw new SyntaxError('null'); | ||
} | ||
ret = JSON.parse(payload as string); | ||
} catch (error) { | ||
if (!(error instanceof SyntaxError)) { | ||
throw error; | ||
} | ||
const status = response.status; | ||
if (response.ok && (status === 204 || status === 205 || requestData.method === 'HEAD')) { | ||
ret = undefined; | ||
} else { | ||
if (DEBUG) { | ||
let message = `The server returned an empty string for ${requestData.method} ${requestData.url}, which cannot be parsed into a valid JSON. Return either null or {}.`; | ||
if (payload === '') { | ||
warn(message, true, { | ||
id: 'ds.adapter.returned-empty-string-as-JSON', | ||
}); | ||
throw error; | ||
} | ||
|
||
// eslint-disable-next-line no-console | ||
console.warn('This response was unable to be parsed as json.', payload); | ||
} | ||
|
||
// eslint-disable-next-line no-console | ||
console.warn('This response was unable to be parsed as json.', payload); | ||
} | ||
} | ||
return resolve(ret); | ||
} | ||
|
||
export function determineBodyPromise( | ||
response: Response, | ||
requestData: JQueryAjaxSettings | ||
): Promise<object | string | undefined> { | ||
// response.text() may resolve or reject | ||
// it is a native promise, may not have finally | ||
return response.text().then( | ||
function(payload) { | ||
return _determineBodyPromise(response, requestData, payload); | ||
}, | ||
function(payload) { | ||
return _determineBodyPromise(response, requestData, payload); | ||
} | ||
return ret; | ||
}); | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters