Report the message when a browser error event with a message but no error occurs
This commit is contained in:
@@ -7698,8 +7698,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
this.handleFinalError = error => {
|
||||
this.onException(error);
|
||||
this.handleFinalError = (error, event) => {
|
||||
this.onException(errorOrMsgForGlobalError(error, event));
|
||||
};
|
||||
this.globalErrors.pushListener(this.handleFinalError);
|
||||
this.run(0);
|
||||
@@ -7729,10 +7729,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.recordError_(iterativeIndex);
|
||||
};
|
||||
|
||||
function handleError(error) {
|
||||
// TODO probably shouldn't next() right away here.
|
||||
// That makes debugging async failures much more confusing.
|
||||
onException(error);
|
||||
function handleError(error, event) {
|
||||
onException(errorOrMsgForGlobalError(error, event));
|
||||
}
|
||||
const cleanup = once(() => {
|
||||
if (timeoutId !== void 0) {
|
||||
@@ -7918,6 +7916,17 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
}
|
||||
|
||||
function errorOrMsgForGlobalError(error, event) {
|
||||
// TODO: In cases where error is a string or undefined, the error message
|
||||
// that gets sent to reporters will be `${message} thrown`, which could
|
||||
// be improved to not say "thrown" when the cause wasn't necessarily
|
||||
// an exception or to provide hints about throwing Errors rather than
|
||||
// strings.
|
||||
return (
|
||||
error || (event && event.message) || 'Global error event with no message'
|
||||
);
|
||||
}
|
||||
|
||||
return QueueRunner;
|
||||
};
|
||||
|
||||
|
||||
@@ -459,6 +459,32 @@ describe('QueueRunner', function() {
|
||||
expect(nextQueueableFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles a global error event with a message but no error', function() {
|
||||
const queueableFn = {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
fn: function(done) {
|
||||
const currentHandler = globalErrors.pushListener.calls.mostRecent()
|
||||
.args[0];
|
||||
currentHandler(undefined, { message: 'nope' });
|
||||
},
|
||||
timeout: 1
|
||||
};
|
||||
const onException = jasmine.createSpy('onException');
|
||||
const globalErrors = {
|
||||
pushListener: jasmine.createSpy('pushListener'),
|
||||
popListener: jasmine.createSpy('popListener')
|
||||
};
|
||||
const queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
onException: onException,
|
||||
globalErrors: globalErrors
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(onException).toHaveBeenCalledWith('nope');
|
||||
});
|
||||
|
||||
it('handles exceptions thrown while waiting for the stack to clear', function() {
|
||||
const queueableFn = {
|
||||
fn: function(done) {
|
||||
@@ -492,6 +518,40 @@ describe('QueueRunner', function() {
|
||||
clearStack.calls.argsFor(0)[0]();
|
||||
expect(onException).toHaveBeenCalledWith(error);
|
||||
});
|
||||
|
||||
it('handles a global error event with no error while waiting for the stack to clear', function() {
|
||||
const queueableFn = {
|
||||
fn: function(done) {
|
||||
done();
|
||||
}
|
||||
};
|
||||
const errorListeners = [];
|
||||
const globalErrors = {
|
||||
pushListener: function(f) {
|
||||
errorListeners.push(f);
|
||||
},
|
||||
popListener: function() {
|
||||
errorListeners.pop();
|
||||
}
|
||||
};
|
||||
const clearStack = jasmine.createSpy('clearStack');
|
||||
const onException = jasmine.createSpy('onException');
|
||||
const queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [queueableFn],
|
||||
globalErrors: globalErrors,
|
||||
clearStack: clearStack,
|
||||
onException: onException
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick();
|
||||
expect(clearStack).toHaveBeenCalled();
|
||||
expect(errorListeners.length).toEqual(1);
|
||||
errorListeners[0](undefined, { message: 'nope' });
|
||||
|
||||
clearStack.calls.argsFor(0)[0]();
|
||||
expect(onException).toHaveBeenCalledWith('nope');
|
||||
});
|
||||
});
|
||||
|
||||
describe('with a function that returns a promise', function() {
|
||||
|
||||
@@ -65,8 +65,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
this.handleFinalError = error => {
|
||||
this.onException(error);
|
||||
this.handleFinalError = (error, event) => {
|
||||
this.onException(errorOrMsgForGlobalError(error, event));
|
||||
};
|
||||
this.globalErrors.pushListener(this.handleFinalError);
|
||||
this.run(0);
|
||||
@@ -96,10 +96,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.recordError_(iterativeIndex);
|
||||
};
|
||||
|
||||
function handleError(error) {
|
||||
// TODO probably shouldn't next() right away here.
|
||||
// That makes debugging async failures much more confusing.
|
||||
onException(error);
|
||||
function handleError(error, event) {
|
||||
onException(errorOrMsgForGlobalError(error, event));
|
||||
}
|
||||
const cleanup = once(() => {
|
||||
if (timeoutId !== void 0) {
|
||||
@@ -285,5 +283,16 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
}
|
||||
|
||||
function errorOrMsgForGlobalError(error, event) {
|
||||
// TODO: In cases where error is a string or undefined, the error message
|
||||
// that gets sent to reporters will be `${message} thrown`, which could
|
||||
// be improved to not say "thrown" when the cause wasn't necessarily
|
||||
// an exception or to provide hints about throwing Errors rather than
|
||||
// strings.
|
||||
return (
|
||||
error || (event && event.message) || 'Global error event with no message'
|
||||
);
|
||||
}
|
||||
|
||||
return QueueRunner;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user