Skip to content

Commit 1f966a0

Browse files
committed
fix(toJson): allow JSON.stringify exceptions to be suppressed
Adds third parameter called options to toJson function (for the time being undocumented, private). Adds support for suppressExceptions option (with test cases) that suppresses any exceptions that JSON.stringify might throw and returns undefined in such case. This fix has been discussed on issue angular#9838
1 parent be6920b commit 1f966a0

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

src/Angular.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -967,8 +967,20 @@ function toJsonReplacer(key, value) {
967967
* @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
968968
* @returns {string|undefined} JSON-ified string representing `obj`.
969969
*/
970-
function toJson(obj, pretty) {
970+
function toJson(obj, pretty, options) {
971971
if (typeof obj === 'undefined') return undefined;
972+
973+
if (!options) options = {};
974+
975+
if (options.suppressExceptions) {
976+
try {
977+
return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
978+
} catch (e) {
979+
// in case JSON.stringify throws, suppress error and return undefined
980+
return undefined;
981+
}
982+
}
983+
972984
return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
973985
}
974986

test/AngularSpec.js

+27
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,33 @@ describe('angular', function() {
12191219
it('should serialize undefined as undefined', function() {
12201220
expect(toJson(undefined)).toEqual(undefined);
12211221
});
1222+
1223+
it('should allow JSON.stringify to throw exceptions by default', function() {
1224+
// create objects with references to each other (circular reference)
1225+
// passing such object to JSON.stringify throws a TypeError
1226+
var a = {}, b = {test: a};
1227+
a.test = b;
1228+
1229+
// prepare toJson function with correct arguments for this test
1230+
var toJsonSuppressedTest = toJson.bind(undefined, a);
1231+
1232+
// it should throw a TypeError
1233+
expect(toJsonSuppressedTest).toThrow();
1234+
});
1235+
1236+
it('should not throw exceptions if suppressExceptions option is passed', function() {
1237+
// create objects with references to each other (circular reference)
1238+
// passing such object to JSON.stringify throws a TypeError
1239+
var a = {}, b = {test: a};
1240+
a.test = b;
1241+
1242+
// prepare toJson function with correct arguments for this test
1243+
var toJsonSuppressedTest = toJson.bind(undefined, a, false, {suppressExceptions: true});
1244+
1245+
// it shouldn't throw a TypeError and it should return undefined
1246+
expect(toJsonSuppressedTest).not.toThrow();
1247+
expect(toJsonSuppressedTest()).toBeUndefined();
1248+
});
12221249
});
12231250

12241251
describe('isElement', function() {

0 commit comments

Comments
 (0)