2014-08-12 12:40:17 -04:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
describe('$templateRequest', function() {
|
|
|
|
|
|
2015-10-28 16:39:02 +00:00
|
|
|
describe('provider', function() {
|
|
|
|
|
|
|
|
|
|
describe('httpOptions', function() {
|
|
|
|
|
|
|
|
|
|
it('should default to undefined and fallback to default $http options', function() {
|
|
|
|
|
|
|
|
|
|
var defaultHeader;
|
|
|
|
|
|
|
|
|
|
module(function($templateRequestProvider) {
|
|
|
|
|
expect($templateRequestProvider.httpOptions()).toBeUndefined();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
inject(function($templateRequest, $http, $templateCache) {
|
2016-03-13 13:20:30 +01:00
|
|
|
spyOn($http, 'get').and.callThrough();
|
2015-10-28 16:39:02 +00:00
|
|
|
|
|
|
|
|
$templateRequest('tpl.html');
|
|
|
|
|
|
|
|
|
|
expect($http.get).toHaveBeenCalledOnceWith('tpl.html', {
|
|
|
|
|
cache: $templateCache,
|
2016-07-20 15:45:04 +02:00
|
|
|
transformResponse: []
|
2015-10-28 16:39:02 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should be configurable', function() {
|
|
|
|
|
|
|
|
|
|
function someTransform() {}
|
|
|
|
|
|
2015-10-29 13:24:55 +02:00
|
|
|
module(function($templateRequestProvider) {
|
2015-10-28 16:39:02 +00:00
|
|
|
|
|
|
|
|
// Configure the template request service to provide specific headers and transforms
|
|
|
|
|
$templateRequestProvider.httpOptions({
|
|
|
|
|
headers: { Accept: 'moo' },
|
|
|
|
|
transformResponse: [someTransform]
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
inject(function($templateRequest, $http, $templateCache) {
|
2016-03-13 13:20:30 +01:00
|
|
|
spyOn($http, 'get').and.callThrough();
|
2015-10-28 16:39:02 +00:00
|
|
|
|
|
|
|
|
$templateRequest('tpl.html');
|
|
|
|
|
|
|
|
|
|
expect($http.get).toHaveBeenCalledOnceWith('tpl.html', {
|
|
|
|
|
cache: $templateCache,
|
|
|
|
|
transformResponse: [someTransform],
|
|
|
|
|
headers: { Accept: 'moo' }
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should be allow you to override the cache', function() {
|
|
|
|
|
|
|
|
|
|
var httpOptions = {};
|
|
|
|
|
|
2015-10-29 13:24:55 +02:00
|
|
|
module(function($templateRequestProvider) {
|
2015-10-28 16:39:02 +00:00
|
|
|
$templateRequestProvider.httpOptions(httpOptions);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
inject(function($templateRequest, $http, $cacheFactory) {
|
2016-03-13 13:20:30 +01:00
|
|
|
spyOn($http, 'get').and.callThrough();
|
2015-10-28 16:39:02 +00:00
|
|
|
|
|
|
|
|
var customCache = $cacheFactory('customCache');
|
|
|
|
|
httpOptions.cache = customCache;
|
|
|
|
|
|
|
|
|
|
$templateRequest('tpl.html');
|
|
|
|
|
|
|
|
|
|
expect($http.get).toHaveBeenCalledOnceWith('tpl.html', {
|
|
|
|
|
cache: customCache,
|
|
|
|
|
transformResponse: []
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2014-08-12 12:40:17 -04:00
|
|
|
it('should download the provided template file',
|
|
|
|
|
inject(function($rootScope, $templateRequest, $httpBackend) {
|
|
|
|
|
|
|
|
|
|
$httpBackend.expectGET('tpl.html').respond('<div>abc</div>');
|
|
|
|
|
|
|
|
|
|
var content;
|
|
|
|
|
$templateRequest('tpl.html').then(function(html) { content = html; });
|
|
|
|
|
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
|
|
|
|
|
expect(content).toBe('<div>abc</div>');
|
|
|
|
|
}));
|
|
|
|
|
|
2014-11-29 11:32:56 +01:00
|
|
|
it('should cache the request to prevent extra downloads',
|
2015-01-05 19:46:58 +01:00
|
|
|
inject(function($rootScope, $templateRequest, $templateCache, $httpBackend) {
|
2014-08-12 12:40:17 -04:00
|
|
|
|
2014-11-29 11:32:56 +01:00
|
|
|
$httpBackend.expectGET('tpl.html').respond('matias');
|
2014-08-12 12:40:17 -04:00
|
|
|
|
2014-11-29 11:32:56 +01:00
|
|
|
var content = [];
|
|
|
|
|
function tplRequestCb(html) {
|
|
|
|
|
content.push(html);
|
|
|
|
|
}
|
2014-08-12 12:40:17 -04:00
|
|
|
|
2014-11-29 11:32:56 +01:00
|
|
|
$templateRequest('tpl.html').then(tplRequestCb);
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
|
|
|
|
|
$templateRequest('tpl.html').then(tplRequestCb);
|
2014-08-12 12:40:17 -04:00
|
|
|
$rootScope.$digest();
|
2014-11-29 11:32:56 +01:00
|
|
|
|
|
|
|
|
expect(content[0]).toBe('matias');
|
|
|
|
|
expect(content[1]).toBe('matias');
|
2015-01-05 19:46:58 +01:00
|
|
|
expect($templateCache.get('tpl.html')).toBe('matias');
|
2014-08-12 12:40:17 -04:00
|
|
|
}));
|
|
|
|
|
|
2018-02-04 10:20:46 +01:00
|
|
|
it('should return the cached value on the first request',
|
|
|
|
|
inject(function($rootScope, $templateRequest, $templateCache, $httpBackend) {
|
|
|
|
|
|
|
|
|
|
$httpBackend.expectGET('tpl.html').respond('matias');
|
|
|
|
|
spyOn($templateCache, 'put').and.returnValue('_matias');
|
|
|
|
|
|
|
|
|
|
var content = [];
|
|
|
|
|
function tplRequestCb(html) {
|
|
|
|
|
content.push(html);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$templateRequest('tpl.html').then(tplRequestCb);
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
|
|
|
|
|
expect(content[0]).toBe('_matias');
|
|
|
|
|
}));
|
|
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
it('should call `$exceptionHandler` on request error', function() {
|
|
|
|
|
module(function($exceptionHandlerProvider) {
|
|
|
|
|
$exceptionHandlerProvider.mode('log');
|
|
|
|
|
});
|
2014-11-29 12:29:54 +01:00
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
inject(function($exceptionHandler, $httpBackend, $templateRequest) {
|
|
|
|
|
$httpBackend.expectGET('tpl.html').respond(404, '', {}, 'Not Found');
|
2014-11-29 12:29:54 +01:00
|
|
|
|
|
|
|
|
var err;
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
$templateRequest('tpl.html').catch(function(reason) { err = reason; });
|
2014-11-29 12:29:54 +01:00
|
|
|
$httpBackend.flush();
|
|
|
|
|
|
2018-02-20 11:10:03 +00:00
|
|
|
expect(err).toEqualMinErr('$templateRequest', 'tpload',
|
2016-10-05 17:32:37 +03:00
|
|
|
'Failed to load template: tpl.html (HTTP status: 404 Not Found)');
|
2018-02-20 11:10:03 +00:00
|
|
|
expect($exceptionHandler.errors[0]).toEqualMinErr('$templateRequest', 'tpload',
|
2016-10-05 17:32:37 +03:00
|
|
|
'Failed to load template: tpl.html (HTTP status: 404 Not Found)');
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
});
|
|
|
|
|
});
|
2014-11-29 12:29:54 +01:00
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
it('should not call `$exceptionHandler` on request error when `ignoreRequestError` is true',
|
|
|
|
|
function() {
|
|
|
|
|
module(function($exceptionHandlerProvider) {
|
|
|
|
|
$exceptionHandlerProvider.mode('log');
|
|
|
|
|
});
|
2014-08-12 12:40:17 -04:00
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
inject(function($exceptionHandler, $httpBackend, $templateRequest) {
|
|
|
|
|
$httpBackend.expectGET('tpl.html').respond(404);
|
2014-08-12 12:40:17 -04:00
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
var err;
|
|
|
|
|
$templateRequest('tpl.html', true).catch(function(reason) { err = reason; });
|
|
|
|
|
$httpBackend.flush();
|
2014-08-12 12:40:17 -04:00
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
expect(err.status).toBe(404);
|
|
|
|
|
expect($exceptionHandler.errors).toEqual([]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
);
|
2014-08-12 12:40:17 -04:00
|
|
|
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
it('should not call `$exceptionHandler` when the template is empty',
|
|
|
|
|
inject(function($exceptionHandler, $httpBackend, $rootScope, $templateRequest) {
|
|
|
|
|
$httpBackend.expectGET('tpl.html').respond('');
|
|
|
|
|
|
|
|
|
|
var onError = jasmine.createSpy('onError');
|
|
|
|
|
$templateRequest('tpl.html').catch(onError);
|
2014-08-12 12:40:17 -04:00
|
|
|
$rootScope.$digest();
|
|
|
|
|
$httpBackend.flush();
|
fix($q): treat thrown errors as regular rejections
Previously, errors thrown in a promise's `onFulfilled` or `onRejected` handlers were treated in a
slightly different manner than regular rejections:
They were passed to the `$exceptionHandler()` (in addition to being converted to rejections).
The reasoning for this behavior was that an uncaught error is different than a regular rejection, as
it can be caused by a programming error, for example. In practice, this turned out to be confusing
or undesirable for users, since neither native promises nor any other popular promise library
distinguishes thrown errors from regular rejections.
(Note: While this behavior does not go against the Promises/A+ spec, it is not prescribed either.)
This commit removes the distinction, by skipping the call to `$exceptionHandler()`, thus treating
thrown errors as regular rejections.
**Note:**
Unless explicitly turned off, possibly unhandled rejections will still be caught and passed to the
`$exceptionHandler()`, so errors thrown due to programming errors and not otherwise handled (with a
subsequent `onRejected` handler) will not go unnoticed.
Fixes #3174
Fixes #14745
Closes #15213
BREAKING CHANGE:
Previously, throwing an error from a promise's `onFulfilled` or `onRejection` handlers, would result
in passing the error to the `$exceptionHandler()` (in addition to rejecting the promise with the
error as reason).
Now, a thrown error is treated exactly the same as a regular rejection. This applies to all
services/controllers/filters etc that rely on `$q` (including built-in services, such as `$http` and
`$route`). For example, `$http`'s `transformRequest/Response` functions or a route's `redirectTo`
function as well as functions specified in a route's `resolve` object, will no longer result in a
call to `$exceptionHandler()` if they throw an error. Other than that, everything will continue to
behave in the same way; i.e. the promises will be rejected, route transition will be cancelled,
`$routeChangeError` events will be broadcasted etc.
2016-09-30 20:43:31 +03:00
|
|
|
|
|
|
|
|
expect(onError).not.toHaveBeenCalled();
|
|
|
|
|
expect($exceptionHandler.errors).toEqual([]);
|
|
|
|
|
})
|
|
|
|
|
);
|
2014-08-12 12:40:17 -04:00
|
|
|
|
2016-04-22 14:11:30 +02:00
|
|
|
it('should accept empty templates and refuse null or undefined templates in cache',
|
|
|
|
|
inject(function($rootScope, $templateRequest, $templateCache, $sce) {
|
|
|
|
|
|
|
|
|
|
// Will throw on any template not in cache.
|
|
|
|
|
spyOn($sce, 'getTrustedResourceUrl').and.returnValue(false);
|
|
|
|
|
|
|
|
|
|
expect(function() {
|
|
|
|
|
$templateRequest('tpl.html'); // should go through $sce
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
}).toThrow();
|
|
|
|
|
|
|
|
|
|
$templateCache.put('tpl.html'); // is a no-op, so $sce check as well.
|
|
|
|
|
expect(function() {
|
|
|
|
|
$templateRequest('tpl.html');
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
}).toThrow();
|
|
|
|
|
$templateCache.removeAll();
|
|
|
|
|
|
|
|
|
|
$templateCache.put('tpl.html', null); // makes no sense, but it's been added, so trust it.
|
|
|
|
|
expect(function() {
|
|
|
|
|
$templateRequest('tpl.html');
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
}).not.toThrow();
|
|
|
|
|
$templateCache.removeAll();
|
|
|
|
|
|
|
|
|
|
$templateCache.put('tpl.html', ''); // should work (empty template)
|
|
|
|
|
expect(function() {
|
|
|
|
|
$templateRequest('tpl.html');
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
}).not.toThrow();
|
|
|
|
|
$templateCache.removeAll();
|
|
|
|
|
}));
|
|
|
|
|
|
2014-08-12 12:40:17 -04:00
|
|
|
it('should keep track of how many requests are going on',
|
|
|
|
|
inject(function($rootScope, $templateRequest, $httpBackend) {
|
|
|
|
|
|
|
|
|
|
$httpBackend.expectGET('a.html').respond('a');
|
|
|
|
|
$httpBackend.expectGET('b.html').respond('c');
|
|
|
|
|
$templateRequest('a.html');
|
|
|
|
|
$templateRequest('b.html');
|
|
|
|
|
|
|
|
|
|
expect($templateRequest.totalPendingRequests).toBe(2);
|
|
|
|
|
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
|
|
|
|
|
expect($templateRequest.totalPendingRequests).toBe(0);
|
|
|
|
|
|
|
|
|
|
$httpBackend.expectGET('c.html').respond(404);
|
|
|
|
|
$templateRequest('c.html');
|
|
|
|
|
|
|
|
|
|
expect($templateRequest.totalPendingRequests).toBe(1);
|
|
|
|
|
$rootScope.$digest();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$httpBackend.flush();
|
2016-07-20 15:45:04 +02:00
|
|
|
} catch (e) { /* empty */ }
|
2014-08-12 12:40:17 -04:00
|
|
|
|
|
|
|
|
expect($templateRequest.totalPendingRequests).toBe(0);
|
|
|
|
|
}));
|
|
|
|
|
|
2014-10-14 14:51:29 -04:00
|
|
|
it('should not try to parse a response as JSON',
|
|
|
|
|
inject(function($templateRequest, $httpBackend) {
|
|
|
|
|
var spy = jasmine.createSpy('success');
|
|
|
|
|
$httpBackend.expectGET('a.html').respond('{{text}}', {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
});
|
|
|
|
|
$templateRequest('a.html').then(spy);
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
expect(spy).toHaveBeenCalledOnceWith('{{text}}');
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
it('should use custom response transformers (array)', function() {
|
|
|
|
|
module(function($httpProvider) {
|
|
|
|
|
$httpProvider.defaults.transformResponse.push(function(data) {
|
|
|
|
|
return data + '!!';
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
inject(function($templateRequest, $httpBackend) {
|
|
|
|
|
var spy = jasmine.createSpy('success');
|
|
|
|
|
$httpBackend.expectGET('a.html').respond('{{text}}', {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
});
|
|
|
|
|
$templateRequest('a.html').then(spy);
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
expect(spy).toHaveBeenCalledOnceWith('{{text}}!!');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should use custom response transformers (function)', function() {
|
|
|
|
|
module(function($httpProvider) {
|
|
|
|
|
$httpProvider.defaults.transformResponse = function(data) {
|
|
|
|
|
return data + '!!';
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
inject(function($templateRequest, $httpBackend) {
|
|
|
|
|
var spy = jasmine.createSpy('success');
|
|
|
|
|
$httpBackend.expectGET('a.html').respond('{{text}}', {
|
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
|
});
|
|
|
|
|
$templateRequest('a.html').then(spy);
|
|
|
|
|
$httpBackend.flush();
|
|
|
|
|
expect(spy).toHaveBeenCalledOnceWith('{{text}}!!');
|
|
|
|
|
});
|
|
|
|
|
});
|
2014-08-12 12:40:17 -04:00
|
|
|
});
|