Skip to content

Commit

Permalink
Remove feature flagging for ds-extended-errors.
Browse files Browse the repository at this point in the history
The feature was enabled in ember-data@2.13, the feature flagging can
now be removed.

This is a work around to a bug in the feature flagging system used
by ember-data, that will need to be fixed on master branch.
  • Loading branch information
rwjblue committed Jul 29, 2017
1 parent 6e93c5e commit dc90225
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 183 deletions.
16 changes: 0 additions & 16 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,6 @@ entry in `config/features.json`.
Enables `pushPayload` to return the model(s) that are created or
updated via the internal `store.push`.

- `ds-extended-errors` [#3586](https://github.com/emberjs/data/pull/3586) [#4287](https://github.com/emberjs/data/pull/4287)

Enables `extend` method on errors. It means you can extend from `DS.AdapterError`.

```js
const MyCustomError = DS.AdapterError.extend({ message: "My custom error." });
```

It will also add a few new errors to rest adapter based on http status.

* [401] `DS.UnauthorizedError`
* [403] `DS.ForbiddenError`
* [404] `DS.NotFoundError`
* [409] `DS.ConflictError`
* [500] `DS.ServerError`

- `ds-payload-type-hooks` [#4318](https://github.com/emberjs/data/pull/4318)

Adds two new hooks `modelNameFromPayloadType` and `payloadTypeFromModelName`
Expand Down
31 changes: 7 additions & 24 deletions addon/-private/adapters/errors.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import Ember from 'ember';
import { assert } from 'ember-data/-debug';

import isEnabled from '../features';

const EmberError = Ember.Error;

const SOURCE_POINTER_REGEXP = /^\/?data\/(attributes|relationships)\/(.*)/;
Expand Down Expand Up @@ -88,11 +86,6 @@ export function AdapterError(errors, message = 'Adapter operation failed') {
];
}

let extendedErrorsEnabled = false;
if (isEnabled('ds-extended-errors')) {
extendedErrorsEnabled = true;
}

function extendFn(ErrorClass) {
return function({ message: defaultMessage } = {}) {
return extend(ErrorClass, defaultMessage);
Expand All @@ -105,19 +98,14 @@ function extend(ParentErrorClass, defaultMessage) {
ParentErrorClass.call(this, errors, message || defaultMessage);
};
ErrorClass.prototype = Object.create(ParentErrorClass.prototype);

if (extendedErrorsEnabled) {
ErrorClass.extend = extendFn(ErrorClass);
}
ErrorClass.extend = extendFn(ErrorClass);

return ErrorClass;
}

AdapterError.prototype = Object.create(EmberError.prototype);

if (extendedErrorsEnabled) {
AdapterError.extend = extendFn(AdapterError);
}
AdapterError.extend = extendFn(AdapterError);

/**
A `DS.InvalidError` is used by an adapter to signal the external API
Expand Down Expand Up @@ -260,8 +248,7 @@ export const AbortError = extend(AdapterError,
@class UnauthorizedError
@namespace DS
*/
export const UnauthorizedError = extendedErrorsEnabled ?
extend(AdapterError, 'The adapter operation is unauthorized') : null;
export const UnauthorizedError = extend(AdapterError, 'The adapter operation is unauthorized');

/**
A `DS.ForbiddenError` equates to a HTTP `403 Forbidden` response status.
Expand All @@ -273,8 +260,7 @@ export const UnauthorizedError = extendedErrorsEnabled ?
@class ForbiddenError
@namespace DS
*/
export const ForbiddenError = extendedErrorsEnabled ?
extend(AdapterError, 'The adapter operation is forbidden') : null;
export const ForbiddenError = extend(AdapterError, 'The adapter operation is forbidden');

/**
A `DS.NotFoundError` equates to a HTTP `404 Not Found` response status.
Expand Down Expand Up @@ -312,8 +298,7 @@ export const ForbiddenError = extendedErrorsEnabled ?
@class NotFoundError
@namespace DS
*/
export const NotFoundError = extendedErrorsEnabled ?
extend(AdapterError, 'The adapter could not find the resource') : null;
export const NotFoundError = extend(AdapterError, 'The adapter could not find the resource');

/**
A `DS.ConflictError` equates to a HTTP `409 Conflict` response status.
Expand All @@ -325,8 +310,7 @@ export const NotFoundError = extendedErrorsEnabled ?
@class ConflictError
@namespace DS
*/
export const ConflictError = extendedErrorsEnabled ?
extend(AdapterError, 'The adapter operation failed due to a conflict') : null;
export const ConflictError = extend(AdapterError, 'The adapter operation failed due to a conflict');

/**
A `DS.ServerError` equates to a HTTP `500 Internal Server Error` response
Expand All @@ -336,8 +320,7 @@ export const ConflictError = extendedErrorsEnabled ?
@class ServerError
@namespace DS
*/
export const ServerError = extendedErrorsEnabled ?
extend(AdapterError, 'The adapter operation failed due to a server error') : null;
export const ServerError = extend(AdapterError, 'The adapter operation failed due to a server error');

/**
Convert an hash of errors into an array with errors in JSON-API format.
Expand Down
28 changes: 13 additions & 15 deletions addon/adapters/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -969,21 +969,19 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, {
let errors = this.normalizeErrorResponse(status, headers, payload);
let detailedMessage = this.generatedDetailedMessage(status, headers, payload, requestData);

if (isEnabled('ds-extended-errors')) {
switch (status) {
case 401:
return new UnauthorizedError(errors, detailedMessage);
case 403:
return new ForbiddenError(errors, detailedMessage);
case 404:
return new NotFoundError(errors, detailedMessage);
case 409:
return new ConflictError(errors, detailedMessage);
default:
if (status >= 500) {
return new ServerError(errors, detailedMessage);
}
}
switch (status) {
case 401:
return new UnauthorizedError(errors, detailedMessage);
case 403:
return new ForbiddenError(errors, detailedMessage);
case 404:
return new NotFoundError(errors, detailedMessage);
case 409:
return new ConflictError(errors, detailedMessage);
default:
if (status >= 500) {
return new ServerError(errors, detailedMessage);
}
}

return new AdapterError(errors, detailedMessage);
Expand Down
13 changes: 5 additions & 8 deletions addon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {
belongsTo,
hasMany,
global,
isEnabled,
Errors,
RootState,
Model,
Expand Down Expand Up @@ -93,13 +92,11 @@ DS.InvalidError = InvalidError;
DS.TimeoutError = TimeoutError;
DS.AbortError = AbortError;

if (isEnabled('ds-extended-errors')) {
DS.UnauthorizedError = UnauthorizedError;
DS.ForbiddenError = ForbiddenError;
DS.NotFoundError = NotFoundError;
DS.ConflictError = ConflictError;
DS.ServerError = ServerError;
}
DS.UnauthorizedError = UnauthorizedError;
DS.ForbiddenError = ForbiddenError;
DS.NotFoundError = NotFoundError;
DS.ConflictError = ConflictError;
DS.ServerError = ServerError;

DS.errorsHashToArray = errorsHashToArray;
DS.errorsArrayToHash = errorsArrayToHash;
Expand Down
1 change: 0 additions & 1 deletion config/features.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"ds-improved-ajax": null,
"ds-pushpayload-return": null,
"ds-extended-errors": true,
"ds-overhaul-references": null,
"ds-payload-type-hooks": null,
"ds-check-should-serialize-relationships": true,
Expand Down
108 changes: 53 additions & 55 deletions tests/integration/adapter/rest-adapter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2454,78 +2454,76 @@ test('on error appends errorThrown for sanity', function(assert) {
}
});

if (isEnabled('ds-extended-errors')) {
test("rejects promise with a specialized subclass of DS.AdapterError if ajax responds with http error codes", function(assert) {
assert.expect(10);
test("rejects promise with a specialized subclass of DS.AdapterError if ajax responds with http error codes", function(assert) {
assert.expect(10);

var originalAjax = Ember.$.ajax;
var jqXHR = {
getAllResponseHeaders: function() { return ''; }
};
var originalAjax = Ember.$.ajax;
var jqXHR = {
getAllResponseHeaders: function() { return ''; }
};

Ember.$.ajax = function(hash) {
jqXHR.status = 401;
hash.error(jqXHR, 'error');
};
Ember.$.ajax = function(hash) {
jqXHR.status = 401;
hash.error(jqXHR, 'error');
};

Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.UnauthorizedError, 'reason should be an instance of DS.UnauthorizedError');
});
Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.UnauthorizedError, 'reason should be an instance of DS.UnauthorizedError');
});
});

Ember.$.ajax = function(hash) {
jqXHR.status = 403;
hash.error(jqXHR, 'error');
};
Ember.$.ajax = function(hash) {
jqXHR.status = 403;
hash.error(jqXHR, 'error');
};

Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.ForbiddenError, 'reason should be an instance of DS.ForbiddenError');
});
Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.ForbiddenError, 'reason should be an instance of DS.ForbiddenError');
});
});

Ember.$.ajax = function(hash) {
jqXHR.status = 404;
hash.error(jqXHR, 'error');
};
Ember.$.ajax = function(hash) {
jqXHR.status = 404;
hash.error(jqXHR, 'error');
};

Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.NotFoundError, 'reason should be an instance of DS.NotFoundError');
});
Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.NotFoundError, 'reason should be an instance of DS.NotFoundError');
});
});

Ember.$.ajax = function(hash) {
jqXHR.status = 409;
hash.error(jqXHR, 'error');
};
Ember.$.ajax = function(hash) {
jqXHR.status = 409;
hash.error(jqXHR, 'error');
};

Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.ConflictError, 'reason should be an instance of DS.ConflictError');
});
Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.ConflictError, 'reason should be an instance of DS.ConflictError');
});
});

Ember.$.ajax = function(hash) {
jqXHR.status = 500;
hash.error(jqXHR, 'error');
};
Ember.$.ajax = function(hash) {
jqXHR.status = 500;
hash.error(jqXHR, 'error');
};

Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.ServerError, 'reason should be an instance of DS.ServerError');
});
Ember.run(function() {
store.find('post', '1').then(null, function(reason) {
assert.ok(true, 'promise should be rejected');
assert.ok(reason instanceof DS.ServerError, 'reason should be an instance of DS.ServerError');
});

Ember.$.ajax = originalAjax;
});
}

Ember.$.ajax = originalAjax;
});

test('on error wraps the error string in an DS.AdapterError object', function(assert) {
assert.expect(2);
Expand Down
Loading

0 comments on commit dc90225

Please sign in to comment.