From 68ced16517089cbc1fda2d01b0bb80acbcb4f44d Mon Sep 17 00:00:00 2001 From: Chirag Bhatia Date: Sun, 19 Feb 2017 15:56:17 +0530 Subject: [PATCH 1/4] fix($http): JSON parse failure Fixes #15695 --- docs/content/error/$http/baddata.ngdoc | 13 +++++++++++++ src/ng/http.js | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 docs/content/error/$http/baddata.ngdoc diff --git a/docs/content/error/$http/baddata.ngdoc b/docs/content/error/$http/baddata.ngdoc new file mode 100644 index 000000000000..898fc01a27e3 --- /dev/null +++ b/docs/content/error/$http/baddata.ngdoc @@ -0,0 +1,13 @@ +@ngdoc error +@name $http:baddata +@fullName Bad JSON Data +@description + +This error occurs when the data parameter passed to the {@link ng.$http `defaultHttpResponseTransform`} service is not a valid JSON object. +`defaultHttpResponseTransform` expects the first parameter as a valid JSON object if the second parameter of headers specifies a Content-Type of JSON. + +The error message should provide additional context such as the actual value of the parameter that was received. + +To resolve this error, make sure you pass a valid JSON data object to `defaultHttpResponseTransform`. + +For more information, see the {@link ng.$http `defaultHttpResponseTransform`} service API documentation. diff --git a/src/ng/http.js b/src/ng/http.js index a4b54f68fad5..278502c48c40 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -138,7 +138,11 @@ function defaultHttpResponseTransform(data, headers) { if (tempData) { var contentType = headers('Content-Type'); if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) { - data = fromJson(tempData); + try { + data = fromJson(tempData); + } catch (e) { + throw minErr('$http')('baddata', 'Data must be a valid JSON object. Received: {0}', data); + } } } } From 573e0da9eafed970d9fc6ca2ca26e094a605256d Mon Sep 17 00:00:00 2001 From: Chirag Bhatia Date: Mon, 20 Feb 2017 22:31:45 +0530 Subject: [PATCH 2/4] fix($http): JSON parse failure Fixes #15695 --- docs/content/error/$http/baddata.ngdoc | 13 ++++++++----- src/ng/http.js | 3 ++- test/ng/httpSpec.js | 11 +++++++++++ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/content/error/$http/baddata.ngdoc b/docs/content/error/$http/baddata.ngdoc index 898fc01a27e3..984325d7a8df 100644 --- a/docs/content/error/$http/baddata.ngdoc +++ b/docs/content/error/$http/baddata.ngdoc @@ -3,11 +3,14 @@ @fullName Bad JSON Data @description -This error occurs when the data parameter passed to the {@link ng.$http `defaultHttpResponseTransform`} service is not a valid JSON object. -`defaultHttpResponseTransform` expects the first parameter as a valid JSON object if the second parameter of headers specifies a Content-Type of JSON. +The default @{link ng$http#default-transformations `transformResponse`} will try to parse the +response as JSON if the `Content-Type` header is `application/json` or the response looks like a +valid JSON-stringified object or array. +This error occurs when that data is not a valid JSON object. -The error message should provide additional context such as the actual value of the parameter that was received. +The error message should provide additional context such as the actual response. -To resolve this error, make sure you pass a valid JSON data object to `defaultHttpResponseTransform`. +To resolve this error, make sure you pass a valid JSON data object to `transformResponse`. -For more information, see the {@link ng.$http `defaultHttpResponseTransform`} service API documentation. +For more information, see the {@link ng$http#default-transformations `transformResponse`} service +API documentation. diff --git a/src/ng/http.js b/src/ng/http.js index 278502c48c40..b01f679e9e33 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -141,7 +141,8 @@ function defaultHttpResponseTransform(data, headers) { try { data = fromJson(tempData); } catch (e) { - throw minErr('$http')('baddata', 'Data must be a valid JSON object. Received: {0}', data); + throw $httpMinErr('baddata', 'Data must be a valid JSON object. Received: "{0}". ' + + 'Error occurred: "{1}"', data, e); } } } diff --git a/test/ng/httpSpec.js b/test/ng/httpSpec.js index 1318a742125a..2c4eabfd8fc3 100644 --- a/test/ng/httpSpec.js +++ b/test/ng/httpSpec.js @@ -1442,6 +1442,17 @@ describe('$http', function() { expect(callback.calls.argsFor(1)[0]).toBe(null); expect(callback.calls.argsFor(2)[0]).toBe(''); }); + + it('should return JSON data with error message if JSON is invalid', function() { + var errCallback = jasmine.createSpy('error'); + $httpBackend.expect('GET', '/url').respond('{abcd}', {'Content-Type': 'application/json'}); + $http({method: 'GET', url: '/url'}).then(callback).catch(errCallback); + $httpBackend.flush(); + + expect(callback).not.toHaveBeenCalled(); + expect(errCallback).toHaveBeenCalledOnce(); + expect(errCallback.calls.mostRecent().args[0]).toEqualMinErr('$http', 'baddata'); + }); }); }); From 7deaae95b1e80c78721ea35bf0fae7aa7818f838 Mon Sep 17 00:00:00 2001 From: Chirag Bhatia Date: Wed, 22 Feb 2017 01:23:03 +0530 Subject: [PATCH 3/4] fix($http): JSON parse failure Fixes #15695 --- docs/content/error/$http/baddata.ngdoc | 8 +++----- src/ng/http.js | 2 +- test/ng/httpSpec.js | 10 +++++----- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/content/error/$http/baddata.ngdoc b/docs/content/error/$http/baddata.ngdoc index 984325d7a8df..9349b76639c5 100644 --- a/docs/content/error/$http/baddata.ngdoc +++ b/docs/content/error/$http/baddata.ngdoc @@ -3,14 +3,12 @@ @fullName Bad JSON Data @description -The default @{link ng$http#default-transformations `transformResponse`} will try to parse the +The default @{link ng.$http#default-transformations `transformResponse`} will try to parse the response as JSON if the `Content-Type` header is `application/json` or the response looks like a valid JSON-stringified object or array. This error occurs when that data is not a valid JSON object. The error message should provide additional context such as the actual response. -To resolve this error, make sure you pass a valid JSON data object to `transformResponse`. - -For more information, see the {@link ng$http#default-transformations `transformResponse`} service -API documentation. +To resolve this error, make sure you pass valid JSON data to `transformResponse` or use an +appropriate `Content-Type` header for non-JSON data. diff --git a/src/ng/http.js b/src/ng/http.js index b01f679e9e33..fe67455e3ca9 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -142,7 +142,7 @@ function defaultHttpResponseTransform(data, headers) { data = fromJson(tempData); } catch (e) { throw $httpMinErr('baddata', 'Data must be a valid JSON object. Received: "{0}". ' + - 'Error occurred: "{1}"', data, e); + 'Parse error: "{1}"', data, e); } } } diff --git a/test/ng/httpSpec.js b/test/ng/httpSpec.js index 2c4eabfd8fc3..b08c561a3cde 100644 --- a/test/ng/httpSpec.js +++ b/test/ng/httpSpec.js @@ -1446,12 +1446,12 @@ describe('$http', function() { it('should return JSON data with error message if JSON is invalid', function() { var errCallback = jasmine.createSpy('error'); $httpBackend.expect('GET', '/url').respond('{abcd}', {'Content-Type': 'application/json'}); - $http({method: 'GET', url: '/url'}).then(callback).catch(errCallback); - $httpBackend.flush(); + $http.get('/url').then(callback).catch(errCallback); + $httpBackend.flush(); - expect(callback).not.toHaveBeenCalled(); - expect(errCallback).toHaveBeenCalledOnce(); - expect(errCallback.calls.mostRecent().args[0]).toEqualMinErr('$http', 'baddata'); + expect(callback).not.toHaveBeenCalled(); + expect(errCallback).toHaveBeenCalledOnce(); + expect(errCallback.calls.mostRecent().args[0]).toEqualMinErr('$http', 'baddata'); }); }); }); From 91393a2c89339a3e9125e9885f9c80b9686c0c95 Mon Sep 17 00:00:00 2001 From: Chirag Bhatia Date: Sat, 4 Mar 2017 19:26:01 +0530 Subject: [PATCH 4/4] fix($http): JSON parse failure Fixes #15695 --- test/ng/httpSpec.js | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/test/ng/httpSpec.js b/test/ng/httpSpec.js index b08c561a3cde..f03582bdde23 100644 --- a/test/ng/httpSpec.js +++ b/test/ng/httpSpec.js @@ -1369,17 +1369,15 @@ describe('$http', function() { } ); - it('should forward json deserialization errors to the http error handler', - function() { + it('should return JSON data with error message if JSON is invalid', function() { var errCallback = jasmine.createSpy('error'); - - $httpBackend.expect('GET', '/url').respond('abcd', {'Content-Type': 'application/json'}); - $http({method: 'GET', url: '/url'}).then(callback).catch(errCallback); + $httpBackend.expect('GET', '/url').respond('{abcd}', {'Content-Type': 'application/json'}); + $http.get('/url').then(callback).catch(errCallback); $httpBackend.flush(); expect(callback).not.toHaveBeenCalled(); expect(errCallback).toHaveBeenCalledOnce(); - expect(errCallback.calls.mostRecent().args[0]).toEqual(jasmine.any(SyntaxError)); + expect(errCallback.calls.mostRecent().args[0]).toEqualMinErr('$http', 'baddata'); }); }); @@ -1442,17 +1440,6 @@ describe('$http', function() { expect(callback.calls.argsFor(1)[0]).toBe(null); expect(callback.calls.argsFor(2)[0]).toBe(''); }); - - it('should return JSON data with error message if JSON is invalid', function() { - var errCallback = jasmine.createSpy('error'); - $httpBackend.expect('GET', '/url').respond('{abcd}', {'Content-Type': 'application/json'}); - $http.get('/url').then(callback).catch(errCallback); - $httpBackend.flush(); - - expect(callback).not.toHaveBeenCalled(); - expect(errCallback).toHaveBeenCalledOnce(); - expect(errCallback.calls.mostRecent().args[0]).toEqualMinErr('$http', 'baddata'); - }); }); });