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/package.json b/package.json index 90e74054..e049e9e3 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "eslint-plugin-node": "^8.0.0", "eslint-plugin-self": "^1.1.0", "mocha": "^5.2.0", - "prettier": "^1.13.0", + "prettier": "^1.15.3", "vue-eslint-parser": "^4.0.2" }, "engines": { 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 5d44cb87..0ef159d0 100644 --- a/test/prettier.js +++ b/test/prettier.js @@ -92,13 +92,16 @@ const vueRuleTester = new RuleTester({ vueRuleTester.run('prettier', rule, { valid: [ { - code: `\n\n`, + code: `\n\n`, filename: 'valid.vue' } ], invalid: [ Object.assign(loadInvalidFixture('vue'), { filename: 'invalid.vue' + }), + Object.assign(loadInvalidFixture('vue-syntax-error'), { + filename: 'syntax-error.vue' }) ] }); diff --git a/yarn.lock b/yarn.lock index 7159fd29..5ebcdea7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -679,9 +679,9 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^1.13.0: - version "1.14.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.14.3.tgz#90238dd4c0684b7edce5f83b0fb7328e48bd0895" +prettier@^1.15.3: + version "1.15.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a" progress@^2.0.0: version "2.0.0"