Skip to content

Commit 2688f29

Browse files
fix: ensure that errorParser always returns something (#20749)
* add types to api-runner-error-parser * use backtick
1 parent 3e8f7f4 commit 2688f29

File tree

2 files changed

+79
-21
lines changed

2 files changed

+79
-21
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import errorParser from "../api-runner-error-parser"
2+
3+
describe(`error matching`, () => {
4+
test(`it matches "is not defined" errors`, () => {
5+
const match = errorParser({ err: new Error(`foo is not defined`) })
6+
7+
expect(match).toEqual({
8+
id: `11330`,
9+
context: { sourceMessage: `foo is not defined`, arg: `foo` },
10+
})
11+
})
12+
13+
test(`it has a default when no match are found`, () => {
14+
const match = errorParser({ err: new Error(`unknown error`) })
15+
16+
expect(match).toEqual({
17+
id: `11321`,
18+
context: { sourceMessage: `unknown error` },
19+
error: new Error(`unknown error`),
20+
})
21+
})
22+
})
23+
24+
describe(`unkown error parser`, () => {
25+
test(`it handles Errors`, () => {
26+
const match = errorParser({ err: new Error(`error`) })
27+
28+
expect(match.context.sourceMessage).toEqual(`error`)
29+
expect(match.error).toBeTruthy()
30+
})
31+
32+
test(`it handles Strings`, () => {
33+
const match = errorParser({ err: `error` })
34+
35+
expect(match.context.sourceMessage).toEqual(`error`)
36+
expect(match.error).toBeUndefined()
37+
})
38+
39+
test(`it handles arrays of Error`, () => {
40+
const match = errorParser({ err: [new Error(`error`)] })
41+
42+
expect(match.context.sourceMessage).toEqual(`error`)
43+
expect(match.error).toBeTruthy()
44+
})
45+
46+
test(`it handles anything else by returning an empty string`, () => {
47+
const match = errorParser({ err: new Map() })
48+
49+
expect(match.context.sourceMessage).toEqual(``)
50+
expect(match.error).toBeUndefined()
51+
})
52+
})

packages/gatsby/src/utils/api-runner-error-parser.ts

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,36 @@
11
import { IMatch } from "../types"
22

3-
const errorParser = ({ err }): IMatch => {
3+
const errorParser = ({ err }: { err: unknown }): IMatch => {
44
const handlers = [
55
{
66
regex: /(.+) is not defined/m,
7-
cb: (match): IMatch => {
7+
cb: (match: RegExpMatchArray): IMatch => {
88
return {
99
id: `11330`,
1010
context: { sourceMessage: match[0], arg: match[1] },
1111
}
1212
},
1313
},
14-
// Match anything with a generic catch-all error handler
15-
{
16-
regex: /[\s\S]*/gm,
17-
cb: (match): IMatch => {
18-
return {
19-
id: `11321`,
20-
context: { sourceMessage: err instanceof Error ? match[0] : err },
21-
error: err instanceof Error ? err : undefined,
22-
}
23-
},
24-
},
2514
]
2615

27-
let structured
16+
let structured: IMatch | undefined
17+
let errorMessage: string | undefined
18+
19+
// try to handle as many type of err as possible.
20+
// the err might come from a plugin so we don't
21+
// know what we are getting
22+
if (Array.isArray(err)) {
23+
err = err[0]
24+
}
25+
if (err instanceof Error) {
26+
errorMessage = err.message
27+
}
28+
if (typeof err === `string`) {
29+
errorMessage = err
30+
}
2831

2932
for (const { regex, cb } of handlers) {
30-
if (Array.isArray(err)) {
31-
err = err[0]
32-
}
33-
if (err.message) {
34-
err = err.message
35-
}
36-
const matched = err?.match(regex)
33+
const matched = errorMessage?.match(regex)
3734
if (matched) {
3835
structured = {
3936
...cb(matched),
@@ -42,6 +39,15 @@ const errorParser = ({ err }): IMatch => {
4239
}
4340
}
4441

42+
// if we haven't found any known error
43+
if (!structured) {
44+
return {
45+
id: `11321`,
46+
context: { sourceMessage: errorMessage || `` },
47+
error: err instanceof Error ? err : undefined,
48+
}
49+
}
50+
4551
return structured
4652
}
4753

0 commit comments

Comments
 (0)