diff --git a/eslint-plugin-prettier.js b/eslint-plugin-prettier.js index 5ba28817..0c99b131 100644 --- a/eslint-plugin-prettier.js +++ b/eslint-plugin-prettier.js @@ -209,7 +209,40 @@ module.exports = { { filepath } ); - const prettierSource = prettier.format(source, prettierOptions); + // prettier.format() may throw a SyntaxError if it cannot parse the + // source code it is given. Ususally for JS files this isn't a + // problem as ESLint will report invalid syntax before trying to + // pass it to the prettier plugin. However this might be a problem + // for non-JS languages that are handled by a plugin. Notably Vue + // files throw an error if they contain unclosed elements, such as + // `. In this case report an error at the + // point at which parsing failed. + let prettierSource; + try { + prettierSource = prettier.format(source, prettierOptions); + } catch (err) { + if (!(err instanceof SyntaxError)) { + throw err; + } + + let message = 'Parsing error: ' + err.message; + + // Prettier's message contains a codeframe style preview of the + // invalid code and the line/column at which the error occured. + // ESLint shows those pieces of information elsewhere already so + // remove them from the message + if (err.codeFrame) { + message = message.replace(`\n${err.codeFrame}`, ''); + } + if (err.loc) { + message = message.replace(/ \(\d+:\d+\)$/, ''); + } + + context.report({ message, loc: err.loc }); + + return; + } + if (source !== prettierSource) { const differences = generateDifferences(source, prettierSource); diff --git a/test/invalid/vue-syntax-error.txt b/test/invalid/vue-syntax-error.txt new file mode 100644 index 00000000..c1df5184 --- /dev/null +++ b/test/invalid/vue-syntax-error.txt @@ -0,0 +1,26 @@ +CODE: + + + +OUTPUT: + + + +OPTIONS: +[] + +ERRORS: +[ + { + message: 'Parsing error: Unexpected closing tag "template". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags', + line: 3, column: 2 + }, +] diff --git a/test/prettier.js b/test/prettier.js index 1b4a2d79..0ef159d0 100644 --- a/test/prettier.js +++ b/test/prettier.js @@ -99,6 +99,9 @@ vueRuleTester.run('prettier', rule, { invalid: [ Object.assign(loadInvalidFixture('vue'), { filename: 'invalid.vue' + }), + Object.assign(loadInvalidFixture('vue-syntax-error'), { + filename: 'syntax-error.vue' }) ] });