From dc9022575fa7ed1ac0d02bc1bd9824755ae3d97b Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Sat, 29 Jul 2017 18:46:12 -0400 Subject: [PATCH] Remove feature flagging for ds-extended-errors. 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. --- FEATURES.md | 16 --- addon/-private/adapters/errors.js | 31 +---- addon/adapters/rest.js | 28 ++-- addon/index.js | 13 +- config/features.json | 1 - .../integration/adapter/rest-adapter-test.js | 108 ++++++++------- tests/unit/adapter-errors-test.js | 125 +++++++++--------- 7 files changed, 139 insertions(+), 183 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index 77fd5be66b8..f63632aee23 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -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` diff --git a/addon/-private/adapters/errors.js b/addon/-private/adapters/errors.js index 87f1daaa588..b986a0bef96 100644 --- a/addon/-private/adapters/errors.js +++ b/addon/-private/adapters/errors.js @@ -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)\/(.*)/; @@ -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); @@ -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 @@ -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. @@ -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. @@ -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. @@ -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 @@ -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. diff --git a/addon/adapters/rest.js b/addon/adapters/rest.js index e9f77668727..4f3e885bb27 100644 --- a/addon/adapters/rest.js +++ b/addon/adapters/rest.js @@ -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); diff --git a/addon/index.js b/addon/index.js index c8df6d7412c..0d83b663731 100644 --- a/addon/index.js +++ b/addon/index.js @@ -22,7 +22,6 @@ import { belongsTo, hasMany, global, - isEnabled, Errors, RootState, Model, @@ -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; diff --git a/config/features.json b/config/features.json index 9ebda80bd91..ecff8f33518 100644 --- a/config/features.json +++ b/config/features.json @@ -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, diff --git a/tests/integration/adapter/rest-adapter-test.js b/tests/integration/adapter/rest-adapter-test.js index ca66a32330c..0911a8deca9 100644 --- a/tests/integration/adapter/rest-adapter-test.js +++ b/tests/integration/adapter/rest-adapter-test.js @@ -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); diff --git a/tests/unit/adapter-errors-test.js b/tests/unit/adapter-errors-test.js index 9e19c9a7c47..91dda1d0e7a 100644 --- a/tests/unit/adapter-errors-test.js +++ b/tests/unit/adapter-errors-test.js @@ -1,6 +1,5 @@ import Ember from 'ember'; -import { isEnabled } from 'ember-data/-private'; import testInDebug from 'dummy/tests/helpers/test-in-debug'; import {module, test} from 'qunit'; @@ -44,69 +43,67 @@ test('DS.AbortError', function(assert) { assert.equal(error.message, 'The adapter operation was aborted'); }); -if (isEnabled('ds-extended-errors')) { - test('DS.UnauthorizedError', function(assert) { - let error = new DS.UnauthorizedError(); - - assert.ok(error instanceof Error); - assert.ok(error instanceof DS.AdapterError); - assert.ok(error.isAdapterError); - assert.equal(error.message, 'The adapter operation is unauthorized'); - }); - - test('DS.ForbiddenError', function(assert) { - let error = new DS.ForbiddenError(); - - assert.ok(error instanceof Error); - assert.ok(error instanceof DS.AdapterError); - assert.ok(error.isAdapterError); - assert.equal(error.message, 'The adapter operation is forbidden'); - }); - - test('DS.NotFoundError', function(assert) { - let error = new DS.NotFoundError(); - - assert.ok(error instanceof Error); - assert.ok(error instanceof DS.AdapterError); - assert.ok(error.isAdapterError); - assert.equal(error.message, 'The adapter could not find the resource'); - }); - - test('DS.ConflictError', function(assert) { - let error = new DS.ConflictError(); - - assert.ok(error instanceof Error); - assert.ok(error instanceof DS.AdapterError); - assert.ok(error.isAdapterError); - assert.equal(error.message, 'The adapter operation failed due to a conflict'); - }); - - test('DS.ServerError', function(assert) { - let error = new DS.ServerError(); - - assert.ok(error instanceof Error); - assert.ok(error instanceof DS.AdapterError); - assert.ok(error.isAdapterError); - assert.equal(error.message, 'The adapter operation failed due to a server error'); - }); - - test('CustomAdapterError', function(assert) { - let CustomAdapterError = DS.AdapterError.extend(); - let error = new CustomAdapterError(); - - assert.ok(error instanceof Error); - assert.ok(error instanceof DS.AdapterError); - assert.ok(error.isAdapterError); - assert.equal(error.message, 'Adapter operation failed'); - }); - - test('CustomAdapterError with default message', function(assert) { - let CustomAdapterError = DS.AdapterError.extend({ message: 'custom error!' }); - let error = new CustomAdapterError(); - - assert.equal(error.message, 'custom error!'); - }); -} +test('DS.UnauthorizedError', function(assert) { + let error = new DS.UnauthorizedError(); + + assert.ok(error instanceof Error); + assert.ok(error instanceof DS.AdapterError); + assert.ok(error.isAdapterError); + assert.equal(error.message, 'The adapter operation is unauthorized'); +}); + +test('DS.ForbiddenError', function(assert) { + let error = new DS.ForbiddenError(); + + assert.ok(error instanceof Error); + assert.ok(error instanceof DS.AdapterError); + assert.ok(error.isAdapterError); + assert.equal(error.message, 'The adapter operation is forbidden'); +}); + +test('DS.NotFoundError', function(assert) { + let error = new DS.NotFoundError(); + + assert.ok(error instanceof Error); + assert.ok(error instanceof DS.AdapterError); + assert.ok(error.isAdapterError); + assert.equal(error.message, 'The adapter could not find the resource'); +}); + +test('DS.ConflictError', function(assert) { + let error = new DS.ConflictError(); + + assert.ok(error instanceof Error); + assert.ok(error instanceof DS.AdapterError); + assert.ok(error.isAdapterError); + assert.equal(error.message, 'The adapter operation failed due to a conflict'); +}); + +test('DS.ServerError', function(assert) { + let error = new DS.ServerError(); + + assert.ok(error instanceof Error); + assert.ok(error instanceof DS.AdapterError); + assert.ok(error.isAdapterError); + assert.equal(error.message, 'The adapter operation failed due to a server error'); +}); + +test('CustomAdapterError', function(assert) { + let CustomAdapterError = DS.AdapterError.extend(); + let error = new CustomAdapterError(); + + assert.ok(error instanceof Error); + assert.ok(error instanceof DS.AdapterError); + assert.ok(error.isAdapterError); + assert.equal(error.message, 'Adapter operation failed'); +}); + +test('CustomAdapterError with default message', function(assert) { + let CustomAdapterError = DS.AdapterError.extend({ message: 'custom error!' }); + let error = new CustomAdapterError(); + + assert.equal(error.message, 'custom error!'); +}); const errorsHash = { name: ['is invalid', 'must be a string'],