Skip to content

Commit

Permalink
fix: surface fatal errors from eslint
Browse files Browse the repository at this point in the history
  • Loading branch information
jwbay committed Feb 12, 2022
1 parent e1ee5d5 commit bdea4b1
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/lintResultSerializer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,29 @@ import { VariableDeclarator } from 'estree'

const processCwd = jest.spyOn(process, 'cwd')
const sourceCode = `\nconst foo = 'something';`
let consoleSpy: jest.SpyInstance

beforeEach(() => {
consoleSpy?.mockRestore()
processCwd.mockReturnValue('/cwd')
})

it('should surface fatal errors from eslint', () => {
consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {})

expect(() => {
lint(sourceCode, { parser: 'this-parser-does-not-exist' })
}).toThrowErrorMatchingInlineSnapshot(
`"Encountered fatal error during lint execution: Configured parser 'this-parser-does-not-exist' was not found."`
)

expect(consoleSpy.mock.calls[0][0]).toMatchObject({
ruleId: null,
severity: 2,
message: "Configured parser 'this-parser-does-not-exist' was not found.",
})
})

describe('serializeLintResult supports per-test setup and mocking for lint rules', () => {
test('should not have errors', () => {
processCwd.mockReturnValue('/foo')
Expand All @@ -21,10 +39,11 @@ describe('serializeLintResult supports per-test setup and mocking for lint rules
})
})

function lint(source: string) {
function lint(source: string, config: Linter.Config = {}) {
const linter = new Linter({})
linter.defineRule('my-rule-name', testRule)
const lintMessages = linter.verify(source, {
...config,
rules: { ['my-rule-name']: 'error' },
parserOptions: {
ecmaVersion: 2020,
Expand Down
12 changes: 12 additions & 0 deletions src/lintResultSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export function serializeLintResult({ lintedSource, lintMessages }: SerializeOpt
const uniqueMessages: string[] = []

lintMessages.forEach((lintMessage) => {
checkFatalError(lintMessage)

// ESLint line & column are 1-indexed for better IDE integration, but 0 works
// better for us here
const startLine = lintMessage.line - 1
Expand Down Expand Up @@ -103,6 +105,16 @@ export function serializeLintResult({ lintedSource, lintMessages }: SerializeOpt
return interleaved.join('\n')
}

function checkFatalError(lintMessage: Linter.LintMessage) {
// Allow parsing errors (indicated by non-zero coordinates) to show in the snapshot
// instead of throwing a hard error, but something like a misconfigured parser or
// missing rule should throw
if (lintMessage.fatal && lintMessage.line === 0 && lintMessage.column === 0) {
console.error(lintMessage)
throw new Error(`Encountered fatal error during lint execution: ${lintMessage.message}`)
}
}

function collapseErrorLines(allErrorLines: string[][]) {
let [mainLine, ...rest] = allErrorLines
const collidedErrorLines: string[][] = []
Expand Down

0 comments on commit bdea4b1

Please sign in to comment.