show config errors

master
Brad Cornes 2020-04-23 19:54:01 +01:00
parent 568e078522
commit 15d387ea45
5 changed files with 68 additions and 5 deletions

View File

@ -11,6 +11,18 @@ import invariant from 'tiny-invariant'
import getPlugins from './getPlugins' import getPlugins from './getPlugins'
import getVariants from './getVariants' import getVariants from './getVariants'
import resolveConfig from './resolveConfig' 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 = {}) { function glob(pattern, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -73,7 +85,12 @@ export default async function getClassNames(
}) })
hook.watch() hook.watch()
const config = __non_webpack_require__(configPath) let config
try {
config = __non_webpack_require__(configPath)
} catch (error) {
throw new TailwindConfigError(error)
}
hook.unwatch() hook.unwatch()
const ast = await postcss([tailwindcss(configPath)]).process( const ast = await postcss([tailwindcss(configPath)]).process(
@ -116,8 +133,12 @@ export default async function getClassNames(
const prevDeps = result ? result.dependencies : [] const prevDeps = result ? result.dependencies : []
try { try {
result = await run() result = await run()
} catch (_) { } catch (error) {
onChange(null) if (error instanceof TailwindConfigError) {
onChange({ error })
} else {
onChange(null)
}
return return
} }
if (!arraysEqual(prevDeps, result.dependencies)) { if (!arraysEqual(prevDeps, result.dependencies)) {

View File

@ -63,7 +63,7 @@ connection.onInitialize(
params.rootPath || URI.parse(params.rootUri).path, params.rootPath || URI.parse(params.rootUri).path,
{ {
onChange: (newState: State): void => { onChange: (newState: State): void => {
if (newState) { if (newState && !newState.error) {
state = { ...newState, enabled: true, editor: editorState } state = { ...newState, enabled: true, editor: editorState }
connection.sendNotification('tailwindcss/configUpdated', [ connection.sendNotification('tailwindcss/configUpdated', [
state.configPath, state.configPath,
@ -72,6 +72,20 @@ connection.onInitialize(
]) ])
} else { } else {
state = { enabled: false, editor: editorState } 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 = /^(?<file>.*?):(?<line>[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 // TODO
// connection.sendNotification('tailwindcss/configUpdated', [null]) // connection.sendNotification('tailwindcss/configUpdated', [null])
} }

View File

@ -37,6 +37,7 @@ export type State = null | {
classNames?: ClassNames classNames?: ClassNames
dependencies?: string[] dependencies?: string[]
editor?: EditorState editor?: EditorState
error?: Error
} }
export type DocumentClassList = { export type DocumentClassList = {

View File

@ -12,12 +12,12 @@ import {
WorkspaceFolder, WorkspaceFolder,
Uri, Uri,
} from 'vscode' } from 'vscode'
import { import {
LanguageClient, LanguageClient,
LanguageClientOptions, LanguageClientOptions,
TransportKind, TransportKind,
} from 'vscode-languageclient' } from 'vscode-languageclient'
import { registerConfigErrorHandler } from './lib/registerConfigErrorHandler'
let defaultClient: LanguageClient let defaultClient: LanguageClient
let clients: Map<string, LanguageClient> = new Map() let clients: Map<string, LanguageClient> = new Map()
@ -138,6 +138,10 @@ export function activate(context: ExtensionContext) {
clientOptions clientOptions
) )
client.onReady().then(() => {
registerConfigErrorHandler(client)
})
client.start() client.start()
clients.set(folder.uri.toString(), client) clients.set(folder.uri.toString(), client)
} }

View File

@ -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)
),
})
}
}
)
}