Skip to content

Commit

Permalink
add line number to parser errors
Browse files Browse the repository at this point in the history
  • Loading branch information
AlecAivazis committed Jun 26, 2021
1 parent 0c6addf commit 9cc7c6b
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
28 changes: 21 additions & 7 deletions packages/houdini-common/src/parse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,8 @@ describe('parser tests', () => {
hello
</div>
{:else if foo < 4}
<!--
the crazy <div is to trick the parser into thinking there's
<!--
the crazy <div is to trick the parser into thinking there's
a new tag inside of an expression
-->
<div attribute={foo > && <div 2} foo>
Expand All @@ -364,8 +364,8 @@ describe('parser tests', () => {
expect(result.instance?.end).toMatchInlineSnapshot(`undefined`)

expect(result.module?.content).toMatchInlineSnapshot(`console.log("hello");`)
expect(result.module?.start).toMatchInlineSnapshot(`306`)
expect(result.module?.end).toMatchInlineSnapshot(`368`)
expect(result.module?.start).toMatchInlineSnapshot(`304`)
expect(result.module?.end).toMatchInlineSnapshot(`366`)

checkScriptBounds(doc, result)
})
Expand All @@ -374,11 +374,11 @@ describe('parser tests', () => {
const doc = `<script lang="ts">
console.log('hello')
</script>
<header
class="sticky flex items-center justify-between h-16 top-0 inset-x-0 max-w-7xl px-2 xl:px-0 mx-auto"
>
<svg
class="w-6 h-6"
fill="none"
Expand Down Expand Up @@ -410,7 +410,7 @@ describe('parser tests', () => {
const doc = `<script lang="ts">
const example = object({});
</script>
<div>hello</div>
`

Expand Down Expand Up @@ -446,6 +446,20 @@ describe('parser tests', () => {

checkScriptBounds(doc, result)
})

test('error messages include line number', () => {
try {
// parse the string
parseFile(`
<div`)

fail('no error thrown')
} catch (e) {
const message = (e as Error).message

expect(message).toContain('line 2')
}
})
})

function checkScriptBounds(doc: string, result?: ParsedSvelteFile | null | undefined) {
Expand Down
35 changes: 29 additions & 6 deletions packages/houdini-common/src/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export type ParserOpts = {
filename?: string
}

type ParserError = { message: string; lineNumber: number }

export function parseFile(str: string, opts?: ParserOpts): ParsedSvelteFile {
// look for the instance and module scripts
let instance: StackElement | null
Expand All @@ -20,13 +22,18 @@ export function parseFile(str: string, opts?: ParserOpts): ParsedSvelteFile {
instance = result.instance
module = result.module
} catch (e) {
// pull the message and line number out of the erro
const { message, lineNumber } = e as ParserError

// do we have a filename
const filename = opts?.filename || 'testFile'
// get the error message
const message = (e as Error).message || e

// bubble the error up
throw new Error(`Encountered error while parsing ${filename}: ${message}`)
throw new Error(
`Encountered error${
lineNumber ? ` on line ${lineNumber}` : ''
} while parsing ${filename}: ${message}`
)
}

// build up the result
Expand Down Expand Up @@ -78,10 +85,26 @@ function parse(str: string): { instance: StackElement | null; module: StackEleme
let module: StackElement | null = null
let instance: StackElement | null = null

// count the number of lines
let lineNumber = 1

const ErrorWithLineNumber = (message: string) => {
return {
message,
lineNumber,
}
}

const pop = () => {
const head = content.slice(0, 1)
content = content.slice(1, content.length)
index++

// if we found a newline, increment the line count
if (head === '\n') {
lineNumber++
}

return head
}

Expand All @@ -105,7 +128,7 @@ function parse(str: string): { instance: StackElement | null; module: StackEleme

// if the last character is not what we were looking for
if (tail !== char) {
throw new Error('could not find ' + char)
throw ErrorWithLineNumber('could not find ' + char)
}

return acc
Expand All @@ -131,7 +154,7 @@ function parse(str: string): { instance: StackElement | null; module: StackEleme

// if the last character we saw was not the finishing character, there was a problem
if (head !== finish) {
throw new Error(`did not encounter matching ${finish}.`)
throw ErrorWithLineNumber(`did not encounter matching ${finish}.`)
}
}

Expand Down Expand Up @@ -166,7 +189,7 @@ function parse(str: string): { instance: StackElement | null; module: StackEleme
const innerElement = stack.pop()
const tagName = tag.substr(1)
if (!innerElement || innerElement.tag !== parseTag(tagName).tag) {
throw new Error(
throw ErrorWithLineNumber(
`unexpected closing tag ${parseTag(tagName).tag}, expected ${
innerElement?.tag
}.`
Expand Down

0 comments on commit 9cc7c6b

Please sign in to comment.