Skip to content

Commit fe31e34

Browse files
committed
feat(get-user-trace): create utility to obtain the client's stack frame for debugging
1 parent 19901e1 commit fe31e34

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/__tests__/get-user-trace.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {getUserTrace} from '../get-user-trace'
2+
3+
let globalErrorMock
4+
5+
beforeEach(() => {
6+
// Mock global.Error so we can setup our own stack messages
7+
globalErrorMock = jest.spyOn(global, 'Error')
8+
})
9+
10+
afterEach(() => {
11+
global.Error.mockRestore()
12+
})
13+
14+
test('it returns only client error when frames from node_modules are first', () => {
15+
const stack = `Error: Kaboom
16+
at Object.<anonymous> (/home/john/projects/projects/sample-error/node_modules/@es2050/console/build/index.js:4:10)
17+
at somethingWrong (/home/john/projects/sample-error/error-example.js:2:13)
18+
`
19+
globalErrorMock.mockImplementationOnce(() => ({stack}))
20+
const userTrace = getUserTrace(stack)
21+
expect(userTrace).toEqual(
22+
'/home/john/projects/sample-error/error-example.js:2:13\n',
23+
)
24+
})
25+
26+
test('it returns only client error when node frames are present afterwards', () => {
27+
const stack = `Error: Kaboom
28+
at Object.<anonymous> (/home/john/projects/projects/sample-error/node_modules/@es2050/console/build/index.js:4:10)
29+
at somethingWrong (/home/john/projects/sample-error/error-example.js:2:13)
30+
at Object.<anonymous> (/home/user/Documents/projects/sample-error/error-example.js:14:1)
31+
at Module._compile (internal/modules/cjs/loader.js:1151:30)
32+
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
33+
at Module.load (internal/modules/cjs/loader.js:1000:32)
34+
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
35+
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
36+
at internal/main/run_main_module.js:17:47
37+
`
38+
globalErrorMock.mockImplementationOnce(() => ({stack}))
39+
const userTrace = getUserTrace()
40+
expect(userTrace).toEqual(
41+
'/home/john/projects/sample-error/error-example.js:2:13\n',
42+
)
43+
})

src/get-user-trace.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Frame has the form "at myMethod (location/to/my/file.js:10:2)"
2+
function getFrameLocation(frame) {
3+
const locationStart = frame.indexOf('(') + 1
4+
const locationEnd = frame.indexOf(')')
5+
6+
return frame.slice(locationStart, locationEnd)
7+
}
8+
9+
function getUserTrace() {
10+
const err = new Error()
11+
const firstClientCodeFrame = err.stack
12+
.split('\n')
13+
.slice(1) // Remove first line which has the form "Error: TypeError"
14+
.find(frame => !frame.includes('node_modules/')) // Ignore frames from 3rd party libraries
15+
16+
return `${getFrameLocation(firstClientCodeFrame)}\n`
17+
}
18+
19+
export {getUserTrace}

0 commit comments

Comments
 (0)