Include inner exceptions in stack traces
This commit is contained in:
@@ -3494,18 +3494,38 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stackTrace = new j$.StackTrace(error);
|
const lines = this.stack_(error, {
|
||||||
const lines = filterJasmine(stackTrace);
|
messageHandling: omitMessage ? 'omit' : undefined
|
||||||
let result = '';
|
});
|
||||||
|
return lines.join('\n');
|
||||||
|
};
|
||||||
|
|
||||||
if (stackTrace.message && !omitMessage) {
|
// messageHandling can be falsy (unspecified), 'omit', or 'require'
|
||||||
|
this.stack_ = function(error, { messageHandling }) {
|
||||||
|
let lines = formatProperties(error).split('\n');
|
||||||
|
|
||||||
|
if (lines[lines.length - 1] === '') {
|
||||||
|
lines.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
const stackTrace = new j$.StackTrace(error);
|
||||||
|
lines = lines.concat(filterJasmine(stackTrace));
|
||||||
|
|
||||||
|
if (messageHandling === 'require') {
|
||||||
|
lines.unshift(stackTrace.message || 'Error: ' + error.message);
|
||||||
|
} else if (messageHandling !== 'omit' && stackTrace.message) {
|
||||||
lines.unshift(stackTrace.message);
|
lines.unshift(stackTrace.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
result += formatProperties(error);
|
if (error.cause) {
|
||||||
result += lines.join('\n');
|
const substack = this.stack_(error.cause, {
|
||||||
|
messageHandling: 'require'
|
||||||
|
});
|
||||||
|
substack[0] = 'Caused by: ' + substack[0];
|
||||||
|
lines = lines.concat(substack);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
function filterJasmine(stackTrace) {
|
function filterJasmine(stackTrace) {
|
||||||
|
|||||||
@@ -256,5 +256,51 @@ describe('ExceptionFormatter', function() {
|
|||||||
expect(result).not.toContain('an error');
|
expect(result).not.toContain('an error');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('In environments that support the cause property of Errors', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
const inner = new Error('inner');
|
||||||
|
const outer = new Error('outer', { cause: inner });
|
||||||
|
|
||||||
|
if (!outer.cause) {
|
||||||
|
// Currently: Node 12, Node 14, Safari 14
|
||||||
|
pending('Environment does not support error cause');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('recursively includes the cause in the stack trace in this environment', function() {
|
||||||
|
const subject = new jasmineUnderTest.ExceptionFormatter();
|
||||||
|
const rootCause = new Error('root cause');
|
||||||
|
const proximateCause = new Error('proximate cause', {
|
||||||
|
cause: rootCause
|
||||||
|
});
|
||||||
|
const symptom = new Error('symptom', { cause: proximateCause });
|
||||||
|
|
||||||
|
const lines = subject.stack(symptom).split('\n');
|
||||||
|
// Not all environments include the message in the stack trace.
|
||||||
|
const hasRootMessage = lines[0].indexOf('symptom') !== -1;
|
||||||
|
const firstSymptomStackIx = hasRootMessage ? 1 : 0;
|
||||||
|
|
||||||
|
expect(lines[firstSymptomStackIx])
|
||||||
|
.withContext('first symptom stack frame')
|
||||||
|
.toContain('ExceptionFormatterSpec.js');
|
||||||
|
const proximateCauseMsgIx = lines.indexOf(
|
||||||
|
'Caused by: Error: proximate cause'
|
||||||
|
);
|
||||||
|
expect(proximateCauseMsgIx)
|
||||||
|
.withContext('index of proximate cause message')
|
||||||
|
.toBeGreaterThan(firstSymptomStackIx);
|
||||||
|
expect(lines[proximateCauseMsgIx + 1])
|
||||||
|
.withContext('first proximate cause stack frame')
|
||||||
|
.toContain('ExceptionFormatterSpec.js');
|
||||||
|
const rootCauseMsgIx = lines.indexOf('Caused by: Error: root cause');
|
||||||
|
expect(rootCauseMsgIx)
|
||||||
|
.withContext('index of root cause message')
|
||||||
|
.toBeGreaterThan(proximateCauseMsgIx + 1);
|
||||||
|
expect(lines[rootCauseMsgIx + 1])
|
||||||
|
.withContext('first root cause stack frame')
|
||||||
|
.toContain('ExceptionFormatterSpec.js');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -44,18 +44,38 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stackTrace = new j$.StackTrace(error);
|
const lines = this.stack_(error, {
|
||||||
const lines = filterJasmine(stackTrace);
|
messageHandling: omitMessage ? 'omit' : undefined
|
||||||
let result = '';
|
});
|
||||||
|
return lines.join('\n');
|
||||||
|
};
|
||||||
|
|
||||||
if (stackTrace.message && !omitMessage) {
|
// messageHandling can be falsy (unspecified), 'omit', or 'require'
|
||||||
|
this.stack_ = function(error, { messageHandling }) {
|
||||||
|
let lines = formatProperties(error).split('\n');
|
||||||
|
|
||||||
|
if (lines[lines.length - 1] === '') {
|
||||||
|
lines.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
const stackTrace = new j$.StackTrace(error);
|
||||||
|
lines = lines.concat(filterJasmine(stackTrace));
|
||||||
|
|
||||||
|
if (messageHandling === 'require') {
|
||||||
|
lines.unshift(stackTrace.message || 'Error: ' + error.message);
|
||||||
|
} else if (messageHandling !== 'omit' && stackTrace.message) {
|
||||||
lines.unshift(stackTrace.message);
|
lines.unshift(stackTrace.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
result += formatProperties(error);
|
if (error.cause) {
|
||||||
result += lines.join('\n');
|
const substack = this.stack_(error.cause, {
|
||||||
|
messageHandling: 'require'
|
||||||
|
});
|
||||||
|
substack[0] = 'Caused by: ' + substack[0];
|
||||||
|
lines = lines.concat(substack);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
function filterJasmine(stackTrace) {
|
function filterJasmine(stackTrace) {
|
||||||
|
|||||||
Reference in New Issue
Block a user