Skip to content

Commit ca3abed

Browse files
LekoArtsascorbic
andauthored
Port parts of Structured Errors to TS + Add two more errors (#20597)
* Convert first error files over to TS + add Joi typings * Type more stuff * Error 85926 * Rename tests * Error 85927 * Fix ts type errors for test * WIP: Warn on using .gif in image sharp * Some more typing stuff * Remove WIP .gif stuff * Convert another test to TS * Update snapshot, add describe block * Update snapshot * Fix missing return type * Fix type error and explicitly type error map Co-authored-by: Matt Kane <[email protected]>
1 parent 3af4b3e commit ca3abed

17 files changed

+366
-216
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"@types/fs-extra": "^8.0.1",
1212
"@types/got": "^9.6.9",
1313
"@types/jest": "^24.0.23",
14+
"@types/joi": "^14.3.4",
1415
"@types/lodash": "^4.14.149",
1516
"@types/node": "^12.12.11",
1617
"@types/webpack": "^4.41.0",

packages/gatsby-cli/src/reporter/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const tracer = require(`opentracing`).globalTracer()
4848

4949
const { getErrorFormatter } = require(`./errors`)
5050
const { getStore } = require(`./redux`)
51-
const constructError = require(`../structured-errors/construct-error`)
51+
import constructError from "../structured-errors/construct-error"
5252

5353
const errorFormatter = getErrorFormatter()
5454

packages/gatsby-cli/src/structured-errors/__tests__/construct-error.js renamed to packages/gatsby-cli/src/structured-errors/__tests__/construct-error.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
const constructError = require(`../construct-error`)
1+
import constructError from "../construct-error"
22

33
let log
44
let processExit
55
beforeEach(() => {
66
log = jest.spyOn(console, `log`).mockImplementation(() => {})
7-
processExit = jest.spyOn(process, `exit`).mockImplementation(() => {})
7+
processExit = ((jest.spyOn(
8+
process,
9+
`exit`
10+
) as unknown) as jest.Mock).mockImplementation(() => {})
811

912
log.mockReset()
1013
processExit.mockReset()
1114
})
1215

1316
afterAll(() => {
14-
console.log.mockClear()
15-
process.exit.mockClear()
17+
;(console.log as jest.Mock).mockClear()
18+
;((process.exit as unknown) as jest.Mock).mockClear()
1619
})
1720

1821
test(`it exits on invalid error schema`, () => {

packages/gatsby-cli/src/structured-errors/__tests__/error-map.js renamed to packages/gatsby-cli/src/structured-errors/__tests__/error-map.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { errorMap, defaultError } = require(`../error-map`)
1+
import { errorMap, defaultError } from "../error-map"
22

33
test(`it defaults to generic error`, () => {
44
expect(defaultError).toEqual(

packages/gatsby-cli/src/structured-errors/__tests__/error-schema.js renamed to packages/gatsby-cli/src/structured-errors/__tests__/error-schema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const schema = require(`../error-schema`)
1+
import schema from "../error-schema"
22

33
test(`throws invalid on an invalid error`, () => {
44
expect(schema.validate({ lol: `true` })).rejects.toBeDefined()

packages/gatsby-cli/src/structured-errors/construct-error.js

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import Joi from "@hapi/joi"
2+
import stackTrace from "stack-trace"
3+
import errorSchema from "./error-schema"
4+
import { errorMap, defaultError, IErrorMapEntry, ErrorId } from "./error-map"
5+
import { sanitizeStructuredStackTrace } from "../reporter/errors"
6+
7+
interface IConstructError {
8+
details: {
9+
id?: ErrorId
10+
context?: Record<string, string>
11+
error?: string
12+
[key: string]: unknown
13+
}
14+
}
15+
16+
interface ILocationPosition {
17+
line: number
18+
column: number
19+
}
20+
21+
interface IStructuredError {
22+
code?: string
23+
text: string
24+
stack: {
25+
fileName: string
26+
functionName?: string
27+
lineNumber?: number
28+
columnNumber?: number
29+
}[]
30+
filePath?: string
31+
location?: {
32+
start: ILocationPosition
33+
end?: ILocationPosition
34+
}
35+
error?: unknown
36+
group?: string
37+
level: IErrorMapEntry["level"]
38+
type?: IErrorMapEntry["type"]
39+
docsUrl?: string
40+
}
41+
42+
// Merge partial error details with information from the errorMap
43+
// Validate the constructed object against an error schema
44+
const constructError = ({
45+
details: { id, ...otherDetails },
46+
}: IConstructError): IStructuredError => {
47+
const result: IErrorMapEntry = (id && errorMap[id]) || defaultError
48+
49+
// merge
50+
const structuredError: IStructuredError = {
51+
context: {},
52+
...otherDetails,
53+
...result,
54+
text: result.text(otherDetails.context),
55+
stack: otherDetails.error
56+
? sanitizeStructuredStackTrace(stackTrace.parse(otherDetails.error))
57+
: null,
58+
docsUrl: result.docsUrl || `https://gatsby.dev/issue-how-to`,
59+
}
60+
61+
if (id) {
62+
structuredError.code = id
63+
}
64+
65+
// validate
66+
const { error } = Joi.validate(structuredError, errorSchema)
67+
if (error !== null) {
68+
console.log(`Failed to validate error`, error)
69+
process.exit(1)
70+
}
71+
72+
return structuredError
73+
}
74+
75+
export default constructError

0 commit comments

Comments
 (0)