From 15d387ea45f5eedb0665ce2bdc7d76c646a8b56a Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Thu, 23 Apr 2020 19:54:01 +0100 Subject: [PATCH] show config errors --- packages/tailwindcss-class-names/src/index.js | 27 ++++++++++++++++--- .../tailwindcss-language-server/src/server.ts | 16 ++++++++++- .../src/util/state.ts | 1 + packages/tailwindcss-vscode/src/extension.ts | 6 ++++- .../src/lib/registerConfigErrorHandler.ts | 23 ++++++++++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 packages/tailwindcss-vscode/src/lib/registerConfigErrorHandler.ts diff --git a/packages/tailwindcss-class-names/src/index.js b/packages/tailwindcss-class-names/src/index.js index 1835e66..4b55f76 100644 --- a/packages/tailwindcss-class-names/src/index.js +++ b/packages/tailwindcss-class-names/src/index.js @@ -11,6 +11,18 @@ import invariant from 'tiny-invariant' import getPlugins from './getPlugins' import getVariants from './getVariants' import resolveConfig from './resolveConfig' +import * as util from 'util' + +function TailwindConfigError(error) { + Error.call(this) + Error.captureStackTrace(this, this.constructor) + + this.name = this.constructor.name + this.message = error.message + this.stack = error.stack +} + +util.inherits(TailwindConfigError, Error) function glob(pattern, options = {}) { return new Promise((resolve, reject) => { @@ -73,7 +85,12 @@ export default async function getClassNames( }) hook.watch() - const config = __non_webpack_require__(configPath) + let config + try { + config = __non_webpack_require__(configPath) + } catch (error) { + throw new TailwindConfigError(error) + } hook.unwatch() const ast = await postcss([tailwindcss(configPath)]).process( @@ -116,8 +133,12 @@ export default async function getClassNames( const prevDeps = result ? result.dependencies : [] try { result = await run() - } catch (_) { - onChange(null) + } catch (error) { + if (error instanceof TailwindConfigError) { + onChange({ error }) + } else { + onChange(null) + } return } if (!arraysEqual(prevDeps, result.dependencies)) { diff --git a/packages/tailwindcss-language-server/src/server.ts b/packages/tailwindcss-language-server/src/server.ts index 729d1f0..349ef7e 100644 --- a/packages/tailwindcss-language-server/src/server.ts +++ b/packages/tailwindcss-language-server/src/server.ts @@ -63,7 +63,7 @@ connection.onInitialize( params.rootPath || URI.parse(params.rootUri).path, { onChange: (newState: State): void => { - if (newState) { + if (newState && !newState.error) { state = { ...newState, enabled: true, editor: editorState } connection.sendNotification('tailwindcss/configUpdated', [ state.configPath, @@ -72,6 +72,20 @@ connection.onInitialize( ]) } else { state = { enabled: false, editor: editorState } + if (newState && newState.error) { + const payload: { + message: string + file?: string + line?: number + } = { message: newState.error.message } + const lines = newState.error.stack.toString().split('\n') + const match = /^(?.*?):(?[0-9]+)$/.exec(lines[0]) + if (match) { + payload.file = match.groups.file + payload.line = parseInt(match.groups.line, 10) + } + connection.sendNotification('tailwindcss/configError', [payload]) + } // TODO // connection.sendNotification('tailwindcss/configUpdated', [null]) } diff --git a/packages/tailwindcss-language-server/src/util/state.ts b/packages/tailwindcss-language-server/src/util/state.ts index 175dade..d41127d 100644 --- a/packages/tailwindcss-language-server/src/util/state.ts +++ b/packages/tailwindcss-language-server/src/util/state.ts @@ -37,6 +37,7 @@ export type State = null | { classNames?: ClassNames dependencies?: string[] editor?: EditorState + error?: Error } export type DocumentClassList = { diff --git a/packages/tailwindcss-vscode/src/extension.ts b/packages/tailwindcss-vscode/src/extension.ts index 81ca5e1..e27a99c 100755 --- a/packages/tailwindcss-vscode/src/extension.ts +++ b/packages/tailwindcss-vscode/src/extension.ts @@ -12,12 +12,12 @@ import { WorkspaceFolder, Uri, } from 'vscode' - import { LanguageClient, LanguageClientOptions, TransportKind, } from 'vscode-languageclient' +import { registerConfigErrorHandler } from './lib/registerConfigErrorHandler' let defaultClient: LanguageClient let clients: Map = new Map() @@ -138,6 +138,10 @@ export function activate(context: ExtensionContext) { clientOptions ) + client.onReady().then(() => { + registerConfigErrorHandler(client) + }) + client.start() clients.set(folder.uri.toString(), client) } diff --git a/packages/tailwindcss-vscode/src/lib/registerConfigErrorHandler.ts b/packages/tailwindcss-vscode/src/lib/registerConfigErrorHandler.ts new file mode 100644 index 0000000..819458e --- /dev/null +++ b/packages/tailwindcss-vscode/src/lib/registerConfigErrorHandler.ts @@ -0,0 +1,23 @@ +import { LanguageClient } from 'vscode-languageclient' +import { window, Uri, Range, Position } from 'vscode' + +export function registerConfigErrorHandler(client: LanguageClient) { + client.onNotification( + 'tailwindcss/configError', + async ({ message, file, line }) => { + const actions: string[] = file ? ['View'] : [] + const action = await window.showErrorMessage( + `Tailwind CSS: ${message}`, + ...actions + ) + if (action === 'View') { + window.showTextDocument(Uri.file(file), { + selection: new Range( + new Position(line - 1, 0), + new Position(line - 1, 0) + ), + }) + } + } + ) +}