Skip to content

Commit 8d1bc59

Browse files
committed
Keep error static properties
1 parent fee7aa7 commit 8d1bc59

File tree

8 files changed

+51
-25
lines changed

8 files changed

+51
-25
lines changed

src/error/main.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@ import { inspect } from 'util'
22

33
import { getMessage } from './message.js'
44
import { printError } from './print.js'
5+
import { getEventProps } from './props.js'
56
import { getStack } from './stack.js'
67

78
const { custom } = inspect
89

910
// Retrieve `error` which sums up all information that can be gathered about
1011
// the event.
1112
export const getError = function ({ name, event }) {
13+
const { stack, ...staticProps } = getEventProps(event)
1214
const message = getMessage({ event, name })
13-
const stack = getStack({ event })
14-
const error = buildError({ name, message, stack })
15-
return { error, stack }
15+
const stackA = getStack(stack)
16+
const error = buildError({ name, message, stack: stackA, staticProps })
17+
return { error, stack: stackA }
1618
}
1719

18-
const buildError = function ({ name, message, stack }) {
20+
const buildError = function ({ name, message, stack, staticProps }) {
1921
const error = new Error(message)
22+
// eslint-disable-next-line fp/no-mutating-assign
23+
Object.assign(error, staticProps)
2024
// `error.name` should not be enumerable, to ensure it is correctly printed.
2125
// eslint-disable-next-line fp/no-mutating-methods
2226
Object.defineProperty(error, 'name', {

src/error/props.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// If event is an error, retrieve static properties except `name` and `message`
2+
export const getEventProps = function ({ nextValue, value }) {
3+
if (nextValue instanceof Error) {
4+
return getErrorProps(nextValue)
5+
}
6+
7+
if (value instanceof Error) {
8+
return getErrorProps(value)
9+
}
10+
11+
return {}
12+
}
13+
14+
const getErrorProps = function (error) {
15+
return { stack: error.stack, ...error }
16+
}

src/error/stack.js

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,7 @@
11
// Retrieve `error.stack` by re-using the original error's stack trace
2-
export const getStack = function ({ event: { nextValue, value } }) {
3-
const stack = getEventStack({ nextValue, value })
4-
const stackA = removeStackHeader({ stack })
5-
return stackA
6-
}
7-
8-
// Find the original error's stack trace
9-
const getEventStack = function ({ nextValue, value }) {
10-
if (nextValue instanceof Error) {
11-
return nextValue.stack
12-
}
13-
14-
if (value instanceof Error) {
15-
return value.stack
16-
}
17-
18-
return ''
19-
}
20-
212
// Remove first line of `Error.stack` as it contains `Error.name|message`,
223
// which is already present in the upper error's `message`
23-
const removeStackHeader = function ({ stack }) {
4+
export const getStack = function (stack = '') {
245
return stack.replace(FIRST_LINE_REGEXP, '')
256
}
267

test/log.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const snapshotArgs = function ([error, level]) {
1616
return [
1717
normalizeMessage(inspect(error), { colors: false }),
1818
String(error),
19+
Object.keys(error),
1920
level,
2021
]
2122
}

test/options/snapshots/testing.js.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,6 +1239,7 @@ Generated by [AVA](https://avajs.dev).
12391239
Uncaught exception: Warning: WarningType: message␊
12401240
[500] Detail␊
12411241
Stack:␊
1242+
error properties: Object({ code: '500', detail: 'Detail' })␊
12421243
at STACK TRACE␊
12431244
12441245
1 spec, 1 failure␊
@@ -1299,6 +1300,8 @@ Generated by [AVA](https://avajs.dev).
12991300
[500] Detail␊
13001301
STACK TRACE␊
13011302
type: Warning␊
1303+
code: "500"␊
1304+
detail: Detail␊
13021305
tapCaught: uncaughtException␊
13031306
test: TAP␊
13041307
...␊
@@ -1977,6 +1980,7 @@ Generated by [AVA](https://avajs.dev).
19771980
Uncaught exception: Warning: WarningType: message␊
19781981
[500] Detail␊
19791982
Stack:␊
1983+
error properties: Object({ code: '500', detail: 'Detail' })␊
19801984
at STACK TRACE␊
19811985
19821986
1 spec, 1 failure␊
@@ -2037,6 +2041,8 @@ Generated by [AVA](https://avajs.dev).
20372041
[500] Detail␊
20382042
STACK TRACE␊
20392043
type: Warning␊
2044+
code: "500"␊
2045+
detail: Detail␊
20402046
tapCaught: uncaughtException␊
20412047
test: TAP␊
20422048
...␊
19 Bytes
Binary file not shown.

test/snapshots/log.js.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
The actual snapshot is saved in `log.js.snap`.
44

5-
Generated by [AVA](https://ava.li).
5+
Generated by [AVA](https://avajs.dev).
66

77
## should fire opts.log() with arguments | multipleResolves
88

@@ -16,13 +16,15 @@ Generated by [AVA](https://ava.li).
1616
`MultipleResolves: a promise was resolved/rejected multiple times:␊
1717
Initially resolved with: { success: true }␊
1818
Then rejected with: Error: message`,
19+
[],
1920
'info',
2021
`i multipleResolves (a promise was resolved multiple times) ␊
2122
Initially resolved with: { success: true }␊
2223
Then resolved again with: { success: true }`,
2324
`MultipleResolves: a promise was resolved multiple times:␊
2425
Initially resolved with: { success: true }␊
2526
Then resolved again with: { success: true }`,
27+
[],
2628
'info',
2729
`i multipleResolves (a promise was multiple times) ␊
2830
Initially rejected with: Error: message␊
@@ -31,6 +33,7 @@ Generated by [AVA](https://ava.li).
3133
`MultipleResolves: a promise was resolved/rejected multiple times:␊
3234
Initially rejected with: Error: message␊
3335
Then resolved with: { success: true }`,
36+
[],
3437
'info',
3538
`i multipleResolves (a promise was rejected multiple times) ␊
3639
Initially rejected with: Error: message␊
@@ -39,6 +42,7 @@ Generated by [AVA](https://ava.li).
3942
`MultipleResolves: a promise was rejected multiple times:␊
4043
Initially rejected with: Error: message␊
4144
Then rejected again with: Error: message`,
45+
[],
4246
'info',
4347
]
4448

@@ -50,6 +54,7 @@ Generated by [AVA](https://ava.li).
5054
`× rejectionHandled (a promise was rejected and handled too late) Error: message␊
5155
at STACK TRACE`,
5256
'RejectionHandled: a promise was rejected and handled too late: Error: message',
57+
[],
5358
'error',
5459
]
5560

@@ -61,6 +66,7 @@ Generated by [AVA](https://ava.li).
6166
`× uncaughtException (an exception was thrown but not caught) Error: message␊
6267
at STACK TRACE`,
6368
'UncaughtException: an exception was thrown but not caught: Error: message',
69+
[],
6470
'error',
6571
]
6672

@@ -72,6 +78,7 @@ Generated by [AVA](https://ava.li).
7278
`× unhandledRejection (a promise was rejected but not handled) Error: message␊
7379
at STACK TRACE`,
7480
'UnhandledRejection: a promise was rejected but not handled: Error: message',
81+
[],
7582
'error',
7683
]
7784

@@ -85,21 +92,32 @@ Generated by [AVA](https://ava.li).
8592
at STACK TRACE`,
8693
`Warning: WarningType: message␊
8794
[500] Detail`,
95+
[
96+
'code',
97+
'detail',
98+
],
8899
'warn',
89100
`‼ warning (WarningType1) message␊
90101
[500] ␊
91102
at STACK TRACE`,
92103
`Warning: WarningType1: message␊
93104
[500] `,
105+
[
106+
'code',
107+
],
94108
'warn',
95109
`‼ warning (WarningType2) message␊
96110
Detail␊
97111
at STACK TRACE`,
98112
`Warning: WarningType2: message␊
99113
Detail`,
114+
[
115+
'detail',
116+
],
100117
'warn',
101118
`‼ warning (WarningType3) message␊
102119
at STACK TRACE`,
103120
'Warning: WarningType3: message',
121+
[],
104122
'warn',
105123
]

test/snapshots/log.js.snap

159 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)