Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
feat(errorHandlingConfig): add option to exclude error params from url
Browse files Browse the repository at this point in the history
Specific errors, such as those during nested module loading, can create very long
error urls because the error message includes 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 
Closes #16591
  • Loading branch information
Narretz committed Jun 6, 2018
1 parent bf841d3 commit 3d6c45d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 19 deletions.
19 changes: 16 additions & 3 deletions src/minErr.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
*/

var minErrConfig = {
objectMaxDepth: 5
objectMaxDepth: 5,
urlErrorParamsEnabled: true
};

/**
Expand All @@ -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;
}
Expand All @@ -50,6 +60,7 @@ function isValidObjectMaxDepth(maxDepth) {
return isNumber(maxDepth) && maxDepth > 0;
}


/**
* @description
*
Expand Down Expand Up @@ -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);
Expand Down
64 changes: 48 additions & 16 deletions test/minErrSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,57 @@

describe('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() {
Expand Down Expand Up @@ -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');

Expand All @@ -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');
});

});
});

0 comments on commit 3d6c45d

Please sign in to comment.