取消注释未使用的autoSuggest方法后Monaco Web Editor功能失效求助
我在给Monaco Web Editor添加代码提示功能时遇到异常:即使autoSuggest方法未被主动调用,编辑器的语法着色、格式化、错误高亮等核心功能全部失效;但如果把autoSuggest简化为直接返回空建议列表,所有核心功能又能正常运行(仅无代码提示)。
有问题的TodoLangLanguageService完整代码
import { ExpressionContext } from "../ANTLR/ExpressionsParserGrammarParser"; import * as monaco from "monaco-editor-core"; import { ILanguageError } from "../todo-lang/ILanguageError"; import { calcFormatted } from "../todo-lang/FormatterVisitor"; import { parseAndGetASTRoot, parseAndGetSyntaxErrors } from "../todo-lang/parser"; export default class TodoLangLanguageService { validate(code: string): ILanguageError[] { const syntaxErrors: ILanguageError[] = parseAndGetSyntaxErrors(code); const ast: ExpressionContext = parseAndGetASTRoot(code); return syntaxErrors;//.concat(checkSemanticRules(ast)); } format(code: string): string { return calcFormatted(code).value } autoSuggest(code: string, line: number, charPosInLine: number): monaco.languages.CompletionList { const syntaxErrors: ILanguageError[] = parseAndGetSyntaxErrors(code); let completeonItems: Array<monaco.languages.CompletionItem> = syntaxErrors.filter(err => err.startLineNumber == line && err.startColumn == charPosInLine).map(e => { let ci: monaco.languages.CompletionItem = { label: e.message, /** * The kind of this completion item. Based on the kind * an icon is chosen by the editor. */ kind: monaco.languages.CompletionItemKind.Field, insertText: e.message, range: { /** * Line number on which the range starts (starts at 1). */ startLineNumber: e.startLineNumber, /** * Column on which the range starts in line `startLineNumber` (starts at 1). */ startColumn: e.startColumn, /** * Line number on which the range ends. */ endLineNumber: e.endLineNumber, /** * Column on which the range ends in line `endLineNumber`. */ endColumn: e.endColumn } } return ci; }) let ci:monaco.languages.CompletionList={ suggestions:completeonItems } return ci; } }
可正常运行的简化版autoSuggest方法
autoSuggest(code: string, line: number, charPosInLine: number): monaco.languages.CompletionList { const syntaxErrors: ILanguageError[] = parseAndGetSyntaxErrors(code); let ci:monaco.languages.CompletionList={ suggestions:[] } return ci; }
项目package.json配置
{ "name": "todolangeditor", "version": "1.0.0", "description": "TodoLang editor", "scripts": { "start": "webpack-dev-server --hot --open", "antlr4ts": "antlr4ts ./ExpressionsParserGrammar.g4 -visitor -o ./src/ANTLR" }, "author": "Open", "license": "ISC", "dependencies": { "antlr4ts": "^0.5.0-alpha.3", "monaco-editor-core": "^0.18.1", "react": "^16.8.6", "react-dom": "^16.8.6" }, "devDependencies": { "@types/react": "^16.8.12", "@types/react-dom": "^16.8.3", "antlr4ts-cli": "^0.5.0-alpha.3", "css-loader": "^3.3.0", "html-webpack-plugin": "^3.2.0", "style-loader": "^1.0.1", "ts-loader": "^5.3.3", "typescript": "^3.4.2", "webpack": "^4.29.6", "webpack-cli": "^3.3.0", "webpack-dev-server": "^3.2.1" } }
npm install执行日志(仅警告)
npm WARN deprecated set-value@2.0.0: Critical bug fixed in v3.0.1,please upgrade to the latest version.
npm WARN deprecated set-value@0.4.3: Critical bug fixed in v3.0.1, please upgrade to the latest version.
npm WARN deprecated urix@0.1.0: Please see deprecated notice.
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
npm WARN deprecated resolve-url@0.2.1: deprecated notice.
npm WARN deprecated source-map-url@0.4.0: See deprecated notice.
npm WARN deprecated html-webpack-plugin@3.2.0: 3.x is no longer supported
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.4.0: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic.
npm WARN deprecated source-map-resolve@0.5.2: See deprecated notice.added 726 packages, and audited 727 packages in 4s
63 packages are looking for funding run
npm fundfor details17 vulnerabilities (1 moderate, 8 high, 8 critical)
To address issues that do not require attention, run: npm audit fix
To address all issues (including breaking changes), run: npm audit fix --force
Run
npm auditfor details.
问题原因与解决方法
核心原因
Monaco编辑器会在用户输入时自动触发补全请求,即使你没主动调用autoSuggest方法。有问题的实现中,parseAndGetSyntaxErrors或后续的数组处理逻辑可能抛出未捕获异常,导致整个语言服务崩溃,进而影响语法着色、格式化等其他依赖语言服务的功能。
具体修复步骤
- 添加异常捕获:在
autoSuggest中包裹try-catch,避免异常扩散影响其他功能:
autoSuggest(code: string, line: number, charPosInLine: number): monaco.languages.CompletionList { try { const syntaxErrors: ILanguageError[] = parseAndGetSyntaxErrors(code); let completeonItems: Array<monaco.languages.CompletionItem> = syntaxErrors .filter(err => err.startLineNumber === line && err.startColumn === charPosInLine) .map(e => { // 校验字段合法性,避免访问undefined属性报错 if (!e.startLineNumber || !e.startColumn || !e.endLineNumber || !e.endColumn) { return null; } return { label: e.message, kind: monaco.languages.CompletionItemKind.Field, insertText: e.message, range: { startLineNumber: e.startLineNumber, startColumn: e.startColumn, endLineNumber: e.endLineNumber, endColumn: e.endColumn } } }) .filter(item => item !== null); // 过滤无效项 return { suggestions: completeonItems }; } catch (err) { console.error('AutoSuggest异常:', err); return { suggestions: [] }; } }
- 检查解析器稳定性:确认
parseAndGetSyntaxErrors方法不会因语法错误代码抛出异常,确保它始终返回合法的ILanguageError数组。 - 升级依赖(可选):执行
npm audit fix --force更新有漏洞的依赖包,避免潜在的底层bug影响。
内容的提问来源于stack exchange,提问作者Vladimir Kozhaev

