提交 1d921de3 编写于 作者: M Martin Aeschlimann

[html] catch exceptions in handlers

上级 1cf80327
...@@ -16,6 +16,7 @@ import { format } from './modes/formatting'; ...@@ -16,6 +16,7 @@ import { format } from './modes/formatting';
import { pushAll } from './utils/arrays'; import { pushAll } from './utils/arrays';
import { getDocumentContext } from './utils/documentContext'; import { getDocumentContext } from './utils/documentContext';
import uri from 'vscode-uri'; import uri from 'vscode-uri';
import { formatError, runSafe } from './utils/errors';
import * as nls from 'vscode-nls'; import * as nls from 'vscode-nls';
...@@ -31,6 +32,10 @@ let connection: IConnection = createConnection(); ...@@ -31,6 +32,10 @@ let connection: IConnection = createConnection();
console.log = connection.console.log.bind(connection.console); console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console); console.error = connection.console.error.bind(connection.console);
process.on('unhandledRejection', (e: any) => {
connection.console.error(formatError(`Unhandled exception`, e));
});
// Create a simple text document manager. The text document manager // Create a simple text document manager. The text document manager
// supports full document sync only // supports full document sync only
let documents: TextDocuments = new TextDocuments(); let documents: TextDocuments = new TextDocuments();
...@@ -208,165 +213,195 @@ function isValidationEnabled(languageId: string, settings: Settings = globalSett ...@@ -208,165 +213,195 @@ function isValidationEnabled(languageId: string, settings: Settings = globalSett
} }
async function validateTextDocument(textDocument: TextDocument) { async function validateTextDocument(textDocument: TextDocument) {
let diagnostics: Diagnostic[] = []; try {
if (textDocument.languageId === 'html') { let diagnostics: Diagnostic[] = [];
let modes = languageModes.getAllModesInDocument(textDocument); if (textDocument.languageId === 'html') {
let settings = await getDocumentSettings(textDocument, () => modes.some(m => !!m.doValidation)); let modes = languageModes.getAllModesInDocument(textDocument);
modes.forEach(mode => { let settings = await getDocumentSettings(textDocument, () => modes.some(m => !!m.doValidation));
if (mode.doValidation && isValidationEnabled(mode.getId(), settings)) { modes.forEach(mode => {
pushAll(diagnostics, mode.doValidation(textDocument, settings)); if (mode.doValidation && isValidationEnabled(mode.getId(), settings)) {
} pushAll(diagnostics, mode.doValidation(textDocument, settings));
}); }
});
}
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
} catch (e) {
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e));
} }
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
} }
connection.onCompletion(async textDocumentPosition => { connection.onCompletion(async textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri); return runSafe(async () => {
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position); let document = documents.get(textDocumentPosition.textDocument.uri);
if (mode && mode.doComplete) { let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
let doComplete = mode.doComplete; if (mode && mode.doComplete) {
if (mode.getId() !== 'html') { let doComplete = mode.doComplete;
connection.telemetry.logEvent({ key: 'html.embbedded.complete', value: { languageId: mode.getId() } }); if (mode.getId() !== 'html') {
connection.telemetry.logEvent({ key: 'html.embbedded.complete', value: { languageId: mode.getId() } });
}
let settings = await getDocumentSettings(document, () => doComplete.length > 2);
return doComplete(document, textDocumentPosition.position, settings);
} }
let settings = await getDocumentSettings(document, () => doComplete.length > 2); return { isIncomplete: true, items: [] };
return doComplete(document, textDocumentPosition.position, settings); }, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`);
}
return { isIncomplete: true, items: [] };
}); });
connection.onCompletionResolve(item => { connection.onCompletionResolve(item => {
let data = item.data; return runSafe(() => {
if (data && data.languageId && data.uri) { let data = item.data;
let mode = languageModes.getMode(data.languageId); if (data && data.languageId && data.uri) {
let document = documents.get(data.uri); let mode = languageModes.getMode(data.languageId);
if (mode && mode.doResolve && document) { let document = documents.get(data.uri);
return mode.doResolve(document, item); if (mode && mode.doResolve && document) {
return mode.doResolve(document, item);
}
} }
} return item;
return item; }, null, `Error while resolving completion proposal`);
}); });
connection.onHover(textDocumentPosition => { connection.onHover(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri); return runSafe(() => {
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position); let document = documents.get(textDocumentPosition.textDocument.uri);
if (mode && mode.doHover) { let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
return mode.doHover(document, textDocumentPosition.position); if (mode && mode.doHover) {
} return mode.doHover(document, textDocumentPosition.position);
return null; }
return null;
}, null, `Error while computing hover for ${textDocumentPosition.textDocument.uri}`);
}); });
connection.onDocumentHighlight(documentHighlightParams => { connection.onDocumentHighlight(documentHighlightParams => {
let document = documents.get(documentHighlightParams.textDocument.uri); return runSafe(() => {
let mode = languageModes.getModeAtPosition(document, documentHighlightParams.position); let document = documents.get(documentHighlightParams.textDocument.uri);
if (mode && mode.findDocumentHighlight) { let mode = languageModes.getModeAtPosition(document, documentHighlightParams.position);
return mode.findDocumentHighlight(document, documentHighlightParams.position); if (mode && mode.findDocumentHighlight) {
} return mode.findDocumentHighlight(document, documentHighlightParams.position);
return []; }
return [];
}, [], `Error while computing document highlights for ${documentHighlightParams.textDocument.uri}`);
}); });
connection.onDefinition(definitionParams => { connection.onDefinition(definitionParams => {
let document = documents.get(definitionParams.textDocument.uri); return runSafe(() => {
let mode = languageModes.getModeAtPosition(document, definitionParams.position); let document = documents.get(definitionParams.textDocument.uri);
if (mode && mode.findDefinition) { let mode = languageModes.getModeAtPosition(document, definitionParams.position);
return mode.findDefinition(document, definitionParams.position); if (mode && mode.findDefinition) {
} return mode.findDefinition(document, definitionParams.position);
return []; }
return [];
}, null, `Error while computing definitions for ${definitionParams.textDocument.uri}`);
}); });
connection.onReferences(referenceParams => { connection.onReferences(referenceParams => {
let document = documents.get(referenceParams.textDocument.uri); return runSafe(() => {
let mode = languageModes.getModeAtPosition(document, referenceParams.position); let document = documents.get(referenceParams.textDocument.uri);
if (mode && mode.findReferences) { let mode = languageModes.getModeAtPosition(document, referenceParams.position);
return mode.findReferences(document, referenceParams.position); if (mode && mode.findReferences) {
} return mode.findReferences(document, referenceParams.position);
return []; }
return [];
}, [], `Error while computing references for ${referenceParams.textDocument.uri}`);
}); });
connection.onSignatureHelp(signatureHelpParms => { connection.onSignatureHelp(signatureHelpParms => {
let document = documents.get(signatureHelpParms.textDocument.uri); return runSafe(() => {
let mode = languageModes.getModeAtPosition(document, signatureHelpParms.position); let document = documents.get(signatureHelpParms.textDocument.uri);
if (mode && mode.doSignatureHelp) { let mode = languageModes.getModeAtPosition(document, signatureHelpParms.position);
return mode.doSignatureHelp(document, signatureHelpParms.position); if (mode && mode.doSignatureHelp) {
} return mode.doSignatureHelp(document, signatureHelpParms.position);
return null; }
return null;
}, null, `Error while computing signature help for ${signatureHelpParms.textDocument.uri}`);
}); });
connection.onDocumentRangeFormatting(async formatParams => { connection.onDocumentRangeFormatting(async formatParams => {
let document = documents.get(formatParams.textDocument.uri); return runSafe(async () => {
let settings = await getDocumentSettings(document, () => true); let document = documents.get(formatParams.textDocument.uri);
if (!settings) { let settings = await getDocumentSettings(document, () => true);
settings = globalSettings; if (!settings) {
} settings = globalSettings;
let unformattedTags: string = settings && settings.html && settings.html.format && settings.html.format.unformatted || ''; }
let enabledModes = { css: !unformattedTags.match(/\bstyle\b/), javascript: !unformattedTags.match(/\bscript\b/) }; let unformattedTags: string = settings && settings.html && settings.html.format && settings.html.format.unformatted || '';
let enabledModes = { css: !unformattedTags.match(/\bstyle\b/), javascript: !unformattedTags.match(/\bscript\b/) };
return format(languageModes, document, formatParams.range, formatParams.options, settings, enabledModes); return format(languageModes, document, formatParams.range, formatParams.options, settings, enabledModes);
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`);
}); });
connection.onDocumentLinks(documentLinkParam => { connection.onDocumentLinks(documentLinkParam => {
let document = documents.get(documentLinkParam.textDocument.uri); return runSafe(() => {
let links: DocumentLink[] = []; let document = documents.get(documentLinkParam.textDocument.uri);
if (document) { let links: DocumentLink[] = [];
let documentContext = getDocumentContext(document.uri, workspaceFolders); if (document) {
languageModes.getAllModesInDocument(document).forEach(m => { let documentContext = getDocumentContext(document.uri, workspaceFolders);
if (m.findDocumentLinks) { languageModes.getAllModesInDocument(document).forEach(m => {
pushAll(links, m.findDocumentLinks(document, documentContext)); if (m.findDocumentLinks) {
} pushAll(links, m.findDocumentLinks(document, documentContext));
}); }
} });
return links; }
return links;
}, [], `Error while document links for ${documentLinkParam.textDocument.uri}`);
}); });
connection.onDocumentSymbol(documentSymbolParms => { connection.onDocumentSymbol(documentSymbolParms => {
let document = documents.get(documentSymbolParms.textDocument.uri); return runSafe(() => {
let symbols: SymbolInformation[] = []; let document = documents.get(documentSymbolParms.textDocument.uri);
languageModes.getAllModesInDocument(document).forEach(m => { let symbols: SymbolInformation[] = [];
if (m.findDocumentSymbols) {
pushAll(symbols, m.findDocumentSymbols(document));
}
});
return symbols;
});
connection.onRequest(DocumentColorRequest.type, params => {
let infos: ColorInformation[] = [];
let document = documents.get(params.textDocument.uri);
if (document) {
languageModes.getAllModesInDocument(document).forEach(m => { languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentColors) { if (m.findDocumentSymbols) {
pushAll(infos, m.findDocumentColors(document)); pushAll(symbols, m.findDocumentSymbols(document));
} }
}); });
} return symbols;
return infos; }, [], `Error while computing document symbols for ${documentSymbolParms.textDocument.uri}`);
});
connection.onRequest(DocumentColorRequest.type, params => {
return runSafe(() => {
let infos: ColorInformation[] = [];
let document = documents.get(params.textDocument.uri);
if (document) {
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentColors) {
pushAll(infos, m.findDocumentColors(document));
}
});
}
return infos;
}, [], `Error while computing document colors for ${params.textDocument.uri}`);
}); });
connection.onRequest(ColorPresentationRequest.type, params => { connection.onRequest(ColorPresentationRequest.type, params => {
let document = documents.get(params.textDocument.uri); return runSafe(() => {
if (document) { let document = documents.get(params.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, params.range.start); if (document) {
if (mode && mode.getColorPresentations) { let mode = languageModes.getModeAtPosition(document, params.range.start);
return mode.getColorPresentations(document, params.color, params.range); if (mode && mode.getColorPresentations) {
return mode.getColorPresentations(document, params.color, params.range);
}
} }
} return [];
return []; }, [], `Error while computing color presentations for ${params.textDocument.uri}`);
}); });
connection.onRequest(TagCloseRequest.type, params => { connection.onRequest(TagCloseRequest.type, params => {
let document = documents.get(params.textDocument.uri); return runSafe(() => {
if (document) { let document = documents.get(params.textDocument.uri);
let pos = params.position; if (document) {
if (pos.character > 0) { let pos = params.position;
let mode = languageModes.getModeAtPosition(document, Position.create(pos.line, pos.character - 1)); if (pos.character > 0) {
if (mode && mode.doAutoClose) { let mode = languageModes.getModeAtPosition(document, Position.create(pos.line, pos.character - 1));
return mode.doAutoClose(document, pos); if (mode && mode.doAutoClose) {
return mode.doAutoClose(document, pos);
}
} }
} }
} return null;
return null; }, null, `Error while computing tag close actions for ${params.textDocument.uri}`);
}); });
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export function formatError(message: string, err: any): string {
if (err instanceof Error) {
let error = <Error>err;
return `${message}: ${error.message}\n${error.stack}`;
} else if (typeof err === 'string') {
return `${message}: ${err}`;
} else if (err) {
return `${message}: ${err.toString()}`;
}
return message;
}
export function runSafe<T>(func: () => Thenable<T> | T, errorVal: T, errorMessage: string): Thenable<T> | T {
try {
let t = func();
if (t instanceof Promise) {
return t.then(void 0, e => {
console.error(formatError(errorMessage, e));
return errorVal;
});
}
return t;
} catch (e) {
console.error(formatError(errorMessage, e));
return errorVal;
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册