From b784557306e8e0b3b2b8d7f9b1393d4a4e4e1629 Mon Sep 17 00:00:00 2001 From: Abdulrahman Almkheibar Date: Mon, 16 Oct 2017 16:02:42 +0200 Subject: [PATCH 1/2] feat(errorHandlingConfig): add option to exclude error params from url Specific errors, such as nested module loading, can create very long error urls because they include the error stack. These urls create visual clutter in the browser console, are often not clickable, and may be rejected by the docs page because they are simply too long. We've already made improvements to the error display in #16283, which excludes the error url from error parameters, which results in cleaner error messages. Further, modern browsers restrict console message length intelligently. This option can still be useful for older browsers like Internet Explorer, or in general to reduce visual clutter in the console. Closes #14744 Closes #15707 Closes #16283 Closes #16299 --- src/minErr.js | 19 ++++++++++--- test/minErrSpec.js | 66 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 20 deletions(-) diff --git a/src/minErr.js b/src/minErr.js index a2f0ddc2d544..234d244f544f 100644 --- a/src/minErr.js +++ b/src/minErr.js @@ -7,7 +7,8 @@ */ var minErrConfig = { - objectMaxDepth: 5 + objectMaxDepth: 5, + urlErrorParamsEnabled: true }; /** @@ -30,12 +31,21 @@ var minErrConfig = { * * `objectMaxDepth` **{Number}** - The max depth for stringifying objects. Setting to a * non-positive or non-numeric value, removes the max depth limit. * Default: 5 + * + * * `urlErrorParamsEnabled` **{Boolean}** - Specifies wether the generated error url will + * contain the parameters of the thrown error. Disabling the parameters can be useful if the + * generated error url is very long. + * + * Default: true. When used without argument, it returns the current value. */ function errorHandlingConfig(config) { if (isObject(config)) { if (isDefined(config.objectMaxDepth)) { minErrConfig.objectMaxDepth = isValidObjectMaxDepth(config.objectMaxDepth) ? config.objectMaxDepth : NaN; } + if (isDefined(config.urlErrorParamsEnabled) && isBoolean(config.urlErrorParamsEnabled)) { + minErrConfig.urlErrorParamsEnabled = config.urlErrorParamsEnabled; + } } else { return minErrConfig; } @@ -50,6 +60,7 @@ function isValidObjectMaxDepth(maxDepth) { return isNumber(maxDepth) && maxDepth > 0; } + /** * @description * @@ -113,8 +124,10 @@ function minErr(module, ErrorConstructor) { message += '\n' + url + (module ? module + '/' : '') + code; - for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { - message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]); + if (minErrConfig.urlErrorParamsEnabled) { + for (i = 0, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') { + message += paramPrefix + 'p' + i + '=' + encodeURIComponent(templateArgs[i]); + } } return new ErrorConstructor(message); diff --git a/test/minErrSpec.js b/test/minErrSpec.js index 4319fd88d569..6b4bf39047b2 100644 --- a/test/minErrSpec.js +++ b/test/minErrSpec.js @@ -1,33 +1,58 @@ 'use strict'; -describe('errors', function() { +fdescribe('errors', function() { var originalObjectMaxDepthInErrorMessage = minErrConfig.objectMaxDepth; + var originalUrlErrorParamsEnabled = minErrConfig.urlErrorParamsEnabled; afterEach(function() { minErrConfig.objectMaxDepth = originalObjectMaxDepthInErrorMessage; + minErrConfig.urlErrorParamsEnabled = originalUrlErrorParamsEnabled; }); describe('errorHandlingConfig', function() { - it('should get default objectMaxDepth', function() { - expect(errorHandlingConfig().objectMaxDepth).toBe(5); - }); + describe('objectMaxDepth',function() { + it('should get default objectMaxDepth', function() { + expect(errorHandlingConfig().objectMaxDepth).toBe(5); + }); + + it('should set objectMaxDepth', function() { + errorHandlingConfig({objectMaxDepth: 3}); + expect(errorHandlingConfig().objectMaxDepth).toBe(3); + }); - it('should set objectMaxDepth', function() { - errorHandlingConfig({objectMaxDepth: 3}); - expect(errorHandlingConfig().objectMaxDepth).toBe(3); + it('should not change objectMaxDepth when undefined is supplied', function() { + errorHandlingConfig({objectMaxDepth: undefined}); + expect(errorHandlingConfig().objectMaxDepth).toBe(originalObjectMaxDepthInErrorMessage); + }); + + they('should set objectMaxDepth to NaN when $prop is supplied', + [NaN, null, true, false, -1, 0], function(maxDepth) { + errorHandlingConfig({objectMaxDepth: maxDepth}); + expect(errorHandlingConfig().objectMaxDepth).toBeNaN(); + } + ); }); - it('should not change objectMaxDepth when undefined is supplied', function() { - errorHandlingConfig({objectMaxDepth: undefined}); - expect(errorHandlingConfig().objectMaxDepth).toBe(originalObjectMaxDepthInErrorMessage); + + describe('urlErrorParamsEnabled',function() { + + it('should get default urlErrorParamsEnabled', function() { + expect(errorHandlingConfig().urlErrorParamsEnabled).toBe(true); + }); + + it('should set urlErrorParamsEnabled', function() { + errorHandlingConfig({urlErrorParamsEnabled: false}); + expect(errorHandlingConfig().urlErrorParamsEnabled).toBe(false); + errorHandlingConfig({urlErrorParamsEnabled: true}); + expect(errorHandlingConfig().urlErrorParamsEnabled).toBe(true); + }); + + it('should not change its value when non-boolean is supplied', function() { + errorHandlingConfig({urlErrorParamsEnabled: 123}); + expect(errorHandlingConfig().urlErrorParamsEnabled).toBe(originalUrlErrorParamsEnabled); + }); }); - they('should set objectMaxDepth to NaN when $prop is supplied', - [NaN, null, true, false, -1, 0], function(maxDepth) { - errorHandlingConfig({objectMaxDepth: maxDepth}); - expect(errorHandlingConfig().objectMaxDepth).toBeNaN(); - } - ); }); describe('minErr', function() { @@ -165,7 +190,6 @@ describe('errors', function() { .toMatch(/^[\s\S]*\?p0=a&p1=b&p2=value%20with%20space$/); }); - it('should strip error reference urls from the error message parameters', function() { var firstError = testError('firstcode', 'longer string and so on'); @@ -177,5 +201,13 @@ describe('errors', function() { '%3A%2F%2Ferrors.angularjs.org%2F%22NG_VERSION_FULL%22%2Ftest%2Ffirstcode'); }); + it('should not generate URL query parameters when urlErrorParamsEnabled is false', function() { + + errorHandlingConfig({urlErrorParamsEnabled: false}); + + expect(testError('acode', 'aproblem', 'a', 'b', 'c').message).toBe('[test:acode] aproblem\n' + + 'https://errors.angularjs.org/"NG_VERSION_FULL"/test/acode'); + }); + }); }); From 2b2a8df2add220d1e647625672d7687a34cfb030 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Wed, 6 Jun 2018 11:45:27 +0200 Subject: [PATCH 2/2] Remove fdescribe --- test/minErrSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/minErrSpec.js b/test/minErrSpec.js index 6b4bf39047b2..66e018b077c8 100644 --- a/test/minErrSpec.js +++ b/test/minErrSpec.js @@ -1,6 +1,6 @@ 'use strict'; -fdescribe('errors', function() { +describe('errors', function() { var originalObjectMaxDepthInErrorMessage = minErrConfig.objectMaxDepth; var originalUrlErrorParamsEnabled = minErrConfig.urlErrorParamsEnabled;