Skip to content

Commit

Permalink
include stackTrace in result exception object (#2371)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss committed Jan 15, 2024
1 parent 567a491 commit 0f51ea7
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 63 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Please see [CONTRIBUTING.md](./CONTRIBUTING.md) on how to contribute to Cucumber
## [Unreleased]
### Added
- Allow `provided` configuration to be a string ([#2373](https://github.com/cucumber/cucumber-js/pull/2373))
- Include `stackTrace` in result exception object ([#2371](https://github.com/cucumber/cucumber-js/pull/2371))

## [10.2.1] - 2024-01-07
### Fixed
Expand Down
1 change: 1 addition & 0 deletions features/support/formatter_output_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,5 @@ export const ignorableKeys = [
'seconds',
// errors
'message',
'stackTrace',
]
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@
"@cucumber/html-formatter": "21.2.0",
"@cucumber/message-streams": "4.0.1",
"@cucumber/messages": "24.0.1",
"@cucumber/tag-expressions": "6.0.0",
"@cucumber/tag-expressions": "6.1.0",
"assertion-error-formatter": "^3.0.0",
"capital-case": "^1.0.4",
"chalk": "^4.1.2",
Expand Down Expand Up @@ -251,7 +251,7 @@
"yup": "1.2.0"
},
"devDependencies": {
"@cucumber/compatibility-kit": "14.1.0",
"@cucumber/compatibility-kit": "15.0.0",
"@cucumber/query": "12.0.1",
"@microsoft/api-extractor": "7.39.0",
"@sinonjs/fake-timers": "10.0.2",
Expand Down
24 changes: 13 additions & 11 deletions src/runtime/format_error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,29 @@ export function formatError(
error: Error,
filterStackTraces: boolean
): Pick<TestStepResult, 'message' | 'exception'> {
let filteredStack: string
if (filterStackTraces) {
try {
filteredStack = filterStackTrace(errorStackParser.parse(error))
.map((f) => f.source)
.join('\n')
} catch {
// if we weren't able to parse and filter, we'll settle for the original
}
let processedStackTrace: string
try {
const parsedStack = errorStackParser.parse(error)
const filteredStack = filterStackTraces
? filterStackTrace(parsedStack)
: parsedStack
processedStackTrace = filteredStack.map((f) => f.source).join('\n')
} catch {
// if we weren't able to parse and process, we'll settle for the original
}
const message = format(error, {
colorFns: {
errorStack: (stack: string) =>
filteredStack ? `\n${filteredStack}` : stack,
errorStack: (stack: string) => {
return processedStackTrace ? `\n${processedStackTrace}` : stack
},
},
})
return {
message,
exception: {
type: error.name || 'Error',
message: typeof error === 'string' ? error : error.message,
stackTrace: processedStackTrace ?? error.stack,
},
}
}
139 changes: 97 additions & 42 deletions src/runtime/format_error_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,111 @@ import { expect } from 'chai'
import { formatError } from './format_error'

describe('formatError', () => {
function testFormatError(fn: () => void, filterStackTraces: boolean = false) {
try {
fn()
return undefined
} catch (error) {
return formatError(error, filterStackTraces)
describe('type and message', () => {
function testFormatError(fn: () => void) {
try {
fn()
return undefined
} catch (error) {
const {
exception: { type, message },
} = formatError(error, false)
return { type, message }
}
}
}

it('should handle a custom error', () => {
expect(
testFormatError(() => {
assert.ok(false, 'Thing that should have been truthy was falsy!')
}).exception
).to.eql({
type: 'AssertionError',
message: 'Thing that should have been truthy was falsy!',

it('should handle a custom error', () => {
expect(
testFormatError(() => {
assert.ok(false, 'Thing that should have been truthy was falsy!')
})
).to.eql({
type: 'AssertionError',
message: 'Thing that should have been truthy was falsy!',
})
})
})

it('should handle a generic error', () => {
expect(
testFormatError(() => {
throw new Error('A generally bad thing happened!')
}).exception
).to.eql({
type: 'Error',
message: 'A generally bad thing happened!',
it('should handle a generic error', () => {
expect(
testFormatError(() => {
throw new Error('A generally bad thing happened!')
})
).to.eql({
type: 'Error',
message: 'A generally bad thing happened!',
})
})

it('should handle an omitted message', () => {
expect(
testFormatError(() => {
throw new Error()
})
).to.eql({
type: 'Error',
message: '',
})
})
})

it('should handle an omitted message', () => {
expect(
testFormatError(() => {
throw new Error()
}).exception
).to.eql({
type: 'Error',
message: '',
it('should handle a thrown string', () => {
expect(
testFormatError(() => {
throw 'Yikes!'
})
).to.eql({
type: 'Error',
message: 'Yikes!',
})
})
})

it('should handle a thrown string', () => {
expect(
testFormatError(() => {
throw 'Yikes!'
}).exception
).to.eql({
type: 'Error',
message: 'Yikes!',
describe('stack traces', () => {
;[false, true].forEach((filterStackTraces) => {
describe('with filterStackTraces=' + filterStackTraces, () => {
function testFormatError(fn: () => void) {
try {
fn()
return undefined
} catch (error) {
const {
exception: { stackTrace },
} = formatError(error, false)
return stackTrace
}
}

it('should handle a custom error', () => {
expect(
testFormatError(() => {
assert.ok(false, 'Thing that should have been truthy was falsy!')
})
).to.have.string(' at ')
})

it('should handle a generic error', () => {
expect(
testFormatError(() => {
throw new Error('A generally bad thing happened!')
})
).to.have.string(' at ')
})

it('should handle an omitted message', () => {
expect(
testFormatError(() => {
throw new Error()
})
).to.have.string(' at ')
})

it('should handle a thrown string', () => {
expect(
testFormatError(() => {
throw 'Yikes!'
})
).to.be.undefined
})
})
})
})
})
2 changes: 2 additions & 0 deletions src/runtime/test_case_runner_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ describe('TestCaseRunner', () => {
exception: {
type: 'Error',
message: 'fail',
stackTrace: undefined,
},
}

Expand Down Expand Up @@ -316,6 +317,7 @@ describe('TestCaseRunner', () => {
exception: {
type: 'Error',
message: 'Oh no!',
stackTrace: undefined,
},
status: messages.TestStepResultStatus.FAILED,
},
Expand Down

0 comments on commit 0f51ea7

Please sign in to comment.