Improve formatting of AggregateErrors

This commit is contained in:
Steve Gravrock
2026-02-07 18:22:12 -08:00
parent b88ce2d49f
commit 6af5d24b3b
3 changed files with 38 additions and 34 deletions

View File

@@ -4071,15 +4071,16 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
} }
if (Array.isArray(error.errors)) { if (Array.isArray(error.errors)) {
error.errors.forEach((aggregatedError, index) => { for (let i = 0; i < error.errors.length; i++) {
if (aggregatedError instanceof Error) { if (error.errors[i] instanceof Error) {
const substack = this.stack_(aggregatedError, { lines.push('');
const substack = this.stack_(error.errors[i], {
messageHandling: 'require' messageHandling: 'require'
}); });
substack[0] = 'Error ' + (index + 1) + ': ' + substack[0]; substack[0] = 'Error ' + (i + 1) + ': ' + substack[0];
lines = lines.concat(substack); lines = lines.concat(substack.map(x => ' ' + x));
} }
}); }
} }
return lines; return lines;

View File

@@ -369,33 +369,35 @@ describe('ExceptionFormatter', function() {
lines.shift(); lines.shift();
} }
for (let i = 0; i < lines.length; i++) { const filteredLines = lines.filter(x => !x.includes('/jasmine.js:'));
jasmine.debugLog(`Line ${i}: ${lines[i]}`);
for (let i = 0; i < filteredLines.length; i++) {
jasmine.debugLog(`Line ${i} after filtering: ${filteredLines[i]}`);
} }
expect(lines[0]) // Inexact matching because stack frame formatting varies from runtime
.withContext('first stack frame of the overall error') // to runtime
.toMatch(/fn3.*core\/ExceptionFormatterSpec\.js/); const expectedPatterns = [
// Overall error
/fn3.*ExceptionFormatterSpec\.js/,
/ExceptionFormatterSpec\.js/,
/^$/,
const error1MsgIx = lines.findIndex(line => // First nested error
line.includes('Error 1: Error: first error') /^ Error 1: Error: first error$/,
); /^ .*fn1.*ExceptionFormatterSpec\.js/,
expect(error1MsgIx) /^ .*ExceptionFormatterSpec\.js/,
.withContext('first nested error message') /^$/,
.toBeGreaterThan(-1);
expect(lines[error1MsgIx + 1])
.withContext('first stack frame of first nested error')
.toMatch(/fn1.*core\/ExceptionFormatterSpec\.js/);
const error2MsgIx = lines.findIndex(line => // Second nested error
line.includes('Error 2: Error: second error') /^ .*Error 2: Error: second error$/,
/^ .*fn2.*ExceptionFormatterSpec\.js/,
/^ .*ExceptionFormatterSpec\.js/,
];
expect(filteredLines).toEqual(
expectedPatterns.map(p => jasmine.stringMatching(p)),
); );
expect(error2MsgIx)
.withContext('second nested error message')
.toBeGreaterThan(error1MsgIx);
expect(lines[error2MsgIx + 1])
.withContext('first stack frame of second nested error')
.toMatch(/fn2.*core\/ExceptionFormatterSpec\.js/);
}); });
it('handles empty errors array', function() { it('handles empty errors array', function() {

View File

@@ -79,15 +79,16 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
} }
if (Array.isArray(error.errors)) { if (Array.isArray(error.errors)) {
error.errors.forEach((aggregatedError, index) => { for (let i = 0; i < error.errors.length; i++) {
if (aggregatedError instanceof Error) { if (error.errors[i] instanceof Error) {
const substack = this.stack_(aggregatedError, { lines.push('');
const substack = this.stack_(error.errors[i], {
messageHandling: 'require' messageHandling: 'require'
}); });
substack[0] = 'Error ' + (index + 1) + ': ' + substack[0]; substack[0] = 'Error ' + (i + 1) + ': ' + substack[0];
lines = lines.concat(substack); lines = lines.concat(substack.map(x => ' ' + x));
} }
}); }
} }
return lines; return lines;