Skip to content

Commit

Permalink
Merge pull request #2597 from dvoytenko/publog5-rethrow
Browse files Browse the repository at this point in the history
Logging: rethrowAsync facility
  • Loading branch information
dvoytenko committed Mar 15, 2016
2 parents fec0430 + df4568b commit 29c91b5
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 22 deletions.
66 changes: 44 additions & 22 deletions src/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,37 +186,20 @@ export class Log {
if (this.level_ >= LogLevel.ERROR) {
this.msg_(tag, 'ERROR', Array.prototype.slice.call(arguments, 1));
} else {
let error = null;
let message = '';
for (let i = 1; i < arguments.length; i++) {
const arg = arguments[i];
if (arg instanceof Error && !error) {
error = arg;
} else {
if (message) {
message += ' ';
}
message += arg;
}
}
if (!error) {
error = new Error(message);
} else if (message) {
error.message = message + ': ' + error.message;
}
const error = createErrorVargs.apply(null,
Array.prototype.slice.call(arguments, 1));
this.prepareError_(error);
this.win.setTimeout(() => {throw error;});
}
}

/**
* Creates an error object.
* @param {string|!Error} errorOrMessage
* @param {...*} var_args
* @return {!Error}
*/
createError(errorOrMessage) {
const error = typeof errorOrMessage == 'string' ?
new Error(errorOrMessage) : errorOrMessage;
createError(var_args) {
const error = createErrorVargs.apply(null, arguments);
this.prepareError_(error);
return error;
}
Expand Down Expand Up @@ -331,6 +314,45 @@ function pushIfNonEmpty(array, val) {
}


/**
* @param {...*} var_args
* @return {!Error}
* @private
*/
function createErrorVargs(var_args) {
let error = null;
let message = '';
for (let i = 0; i < arguments.length; i++) {
const arg = arguments[i];
if (arg instanceof Error && !error) {
error = arg;
} else {
if (message) {
message += ' ';
}
message += arg;
}
}
if (!error) {
error = new Error(message);
} else if (message) {
error.message = message + ': ' + error.message;
}
return error;
}


/**
* Rethrows the error without terminating the current context. This preserves
* whether the original error designation is a user error or a dev error.
* @param {...*} var_args
*/
export function rethrowAsync(var_args) {
const error = createErrorVargs.apply(null, arguments);
setTimeout(() => {throw error;});
}


/**
* @deprecated Use either publog or devlog
* TODO(dvoytenko, #2527): Remove this constant.
Expand Down
68 changes: 68 additions & 0 deletions test/functional/test-log.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
USER_ERROR_SENTINEL,
dev,
isUserErrorMessage,
rethrowAsync,
user,
} from '../../src/log';
import {setModeForTesting} from '../../src/mode';
Expand Down Expand Up @@ -445,4 +446,71 @@ describe('Logging', () => {
.to.throw('Unknown enum value: "VALUE1"');
});
});


describe('rethrowAsync', () => {
let clock;

beforeEach(() => {
clock = sandbox.useFakeTimers();
});

it('should rethrow error with single message', () => {
rethrowAsync('intended');
expect(() => {
clock.tick(1);
}).to.throw(Error, /^intended$/);
});

it('should rethrow a single error', () => {
const orig = new Error('intended');
rethrowAsync(orig);
let error;
try {
clock.tick(1);
} catch (e) {
error = e;
}
expect(error).to.equal(orig);
expect(error.message).to.equal('intended');
});

it('should rethrow error with many messages', () => {
rethrowAsync('first', 'second', 'third');
let error;
try {
clock.tick(1);
} catch (e) {
error = e;
}
expect(error.message).to.equal('first second third');
});

it('should rethrow error with original error and messages', () => {
const orig = new Error('intended');
rethrowAsync('first', orig, 'second', 'third');
let error;
try {
clock.tick(1);
} catch (e) {
error = e;
}
expect(error).to.equal(orig);
expect(error.message).to.equal('first second third: intended');
});

it('should preserve error suffix', () => {
const orig = user.createError('intended');
expect(isUserErrorMessage(orig.message)).to.be.true;
rethrowAsync('first', orig, 'second');
let error;
try {
clock.tick(1);
} catch (e) {
error = e;
}
expect(error).to.equal(orig);
expect(isUserErrorMessage(error.message)).to.be.true;
});
});
});

0 comments on commit 29c91b5

Please sign in to comment.