如何使用Omnisharp请求文档诊断?调用API遇未实现异常
问题:OmniSharp LSP客户端调用RequestDocumentDiagnostic时抛出NotImplementedException
我通过以下代码向LSP请求文档诊断:
var report = await client.RequestDocumentDiagnostic(new DocumentDiagnosticParams() { TextDocument = textDocument, Identifier = "luau" }); Console.WriteLine(report);
其中client为已初始化的LanguageClient,RequestCompletion、RequestHover等其他方法均可正常工作,但调用RequestDocumentDiagnostic时抛出错误:
Unhandled exception. System.NotImplementedException: The method or operation is not implemented. at OmniSharp.Extensions.LanguageServer.Protocol.Models.RelatedDocumentDiagnosticReport.Converter.ReadJson(JsonReader reader, Type objectType, RelatedDocumentDiagnosticReport existingValue, Boolean hasExistingValue, JsonSerializer serializer) at Newtonsoft.Json.JsonConverter`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer) at Newtonsoft.Json.Linq.JToken.ToObject[T](JsonSerializer jsonSerializer) at OmniSharp.Extensions.JsonRpc.ResponseRouter.ResponseRouterReturnsImpl.Returning[TResponse](CancellationToken cancellationToken) at OmniSharp.Extensions.LanguageServer.Protocol.Progress.ProgressManager.<>c__DisplayClass26_0`1.<<MakeRequest>b__0>d.MoveNext()
尝试用client.SendRequest直接获取诊断信息也未成功,且OmniSharp相关文档稀缺,无法定位问题原因。
原因分析
报错核心是RelatedDocumentDiagnosticReport的JSON转换器未实现ReadJson方法,主要有两个可能:
textDocument/diagnostic是LSP 3.17新增的增量诊断请求,你使用的OmniSharp LSP客户端版本未完整实现该特性的反序列化逻辑;- 对接的Luau LSP服务端可能仍采用旧版的推送式诊断(
textDocument/publishDiagnostics通知),而非请求式诊断接口。
解决办法
1. 切换到推送式诊断接收(推荐)
多数LSP服务端通过publishDiagnostics通知主动推送诊断信息,注册处理器即可接收:
client.RegisterHandler<PublishDiagnosticsParams>((param, token) => { // 遍历处理诊断内容 foreach (var diag in param.Diagnostics) { Console.WriteLine($"[{diag.Severity}] {diag.Range.Start.Line + 1}:{diag.Range.Start.Character + 1} - {diag.Message}"); } return Task.CompletedTask; });
2. 升级OmniSharp客户端版本
检查OmniSharp.Extensions.LanguageServer包版本,升级到最新稳定版,新版本可能已补全RelatedDocumentDiagnosticReport的转换器实现。
3. 手动处理SendRequest的响应
若坚持使用请求式诊断,可通过SendRequest获取原始JSON响应,手动解析避免反序列化失败:
var response = await client.SendRequest<JObject>("textDocument/diagnostic", new DocumentDiagnosticParams() { TextDocument = textDocument, Identifier = "luau" }); // 手动提取诊断列表 var diagnostics = response["items"]?[0]?["diagnostics"]?.ToObject<IEnumerable<Diagnostic>>(); if (diagnostics != null) { foreach (var diag in diagnostics) { Console.WriteLine(diag.Message); } }
4. 验证服务端支持性
先确认Luau LSP服务端是否支持textDocument/diagnostic请求,可在客户端初始化后检查服务端能力:
var serverCapabilities = client.ServerSettings.Capabilities; if (serverCapabilities.DiagnosticProvider == null) { Console.WriteLine("服务端不支持textDocument/diagnostic请求,请使用publishDiagnostics通知"); }
内容的提问来源于stack exchange,提问作者SeizureSalad
相关产品推荐
相关产品推荐

