From 0cf2e42150fe97ee3d13d4c7e8d03664c523be38 Mon Sep 17 00:00:00 2001 From: Andrew Hall Date: Thu, 10 Apr 2025 15:30:26 -0700 Subject: [PATCH] Allow graceful handling of ArgumentException when trying to apply changes to SourceText in LspTextChangesLoader (#11727) Helps mitigate https://github.com/dotnet/vscode-csharp/issues/8147 --- ...icFileProvider.LspTextChangesTextLoader.cs | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs index 5853fc32d21..718def982a7 100644 --- a/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs +++ b/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/LspDynamicFileProvider.LspTextChangesTextLoader.cs @@ -36,20 +36,32 @@ private sealed class LspTextChangesTextLoader( public override async Task LoadTextAndVersionAsync(LoadTextOptions options, CancellationToken cancellationToken) { - if (_document is null) + try { - var text = ApplyChanges(_emptySourceText.Value, _changes); - return TextAndVersion.Create(text, VersionStamp.Default.GetNewerVersion()); - } + if (_document is null) + { + var text = ApplyChanges(_emptySourceText.Value, _changes); + return TextAndVersion.Create(text, VersionStamp.Default.GetNewerVersion()); + } + + var sourceText = await _document.GetTextAsync(cancellationToken).ConfigureAwait(false); - var sourceText = await _document.GetTextAsync(cancellationToken).ConfigureAwait(false); + // Validate the checksum information so the edits are known to be correct - // Validate the checksum information so the edits are known to be correct - if (IsSourceTextMatching(sourceText)) + if (IsSourceTextMatching(sourceText)) + { + var version = await _document.GetTextVersionAsync(cancellationToken).ConfigureAwait(false); + var newText = ApplyChanges(sourceText, _changes); + return TextAndVersion.Create(newText, version.GetNewerVersion()); + } + } + catch (Exception ex) when (ex is not OperationCanceledException) { - var version = await _document.GetTextVersionAsync(cancellationToken).ConfigureAwait(false); - var newText = ApplyChanges(sourceText, _changes); - return TextAndVersion.Create(newText, version.GetNewerVersion()); + // This happens if ApplyChanges tries to apply an invalid TextChange. + // This is recoverable but incurs a perf hit for getting the full text below. + + // TODO: Add ability to capture a fault here in EA. There's something wrong if + // the Checksum matches but the text changes can't be applied. } return await GetFullDocumentFromServerAsync(cancellationToken).ConfigureAwait(false);