Skip to content

Commit 0cc8235

Browse files
Catch and report when we are unable to make an invisible editor (#78236)
2 parents b9d12c3 + 50cc532 commit 0cc8235

16 files changed

+283
-19
lines changed

src/VisualStudio/Core/Def/ProjectSystem/VisualStudioWorkspaceImpl.cs

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Diagnostics.CodeAnalysis;
1010
using System.IO;
1111
using System.Linq;
12+
using System.Runtime.InteropServices;
1213
using System.Text;
1314
using System.Threading;
1415
using System.Threading.Tasks;
@@ -112,6 +113,12 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
112113
private readonly IAsynchronousOperationListener _workspaceListener;
113114
private bool _isExternalErrorDiagnosticUpdateSourceSubscribedToSolutionBuildEvents;
114115

116+
/// <summary>
117+
/// Only read/written on hte UI thread.
118+
/// </summary>
119+
private bool _isShowingDocumentChangeErrorInfoBar = false;
120+
private bool _ignoreDocumentTextChangeErrors;
121+
115122
public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServiceProvider asyncServiceProvider)
116123
: base(VisualStudioMefHostServices.Create(exportProvider))
117124
{
@@ -1192,29 +1199,81 @@ protected override void ApplyAnalyzerConfigDocumentTextChanged(DocumentId docume
11921199

11931200
private void ApplyTextDocumentChange(DocumentId documentId, SourceText newText)
11941201
{
1195-
var containedDocument = ContainedDocument.TryGetContainedDocument(documentId);
1202+
this._threadingContext.ThrowIfNotOnUIThread();
11961203

1197-
if (containedDocument != null)
1198-
{
1199-
containedDocument.UpdateText(newText);
1200-
}
1201-
else
1204+
CodeAnalysis.TextDocument? document = null;
1205+
1206+
try
12021207
{
1203-
if (IsDocumentOpen(documentId))
1204-
{
1205-
var textBuffer = this.CurrentSolution.GetTextDocument(documentId)!.GetTextSynchronously(CancellationToken.None).Container.TryGetTextBuffer();
1208+
document = this.CurrentSolution.GetRequiredTextDocument(documentId);
12061209

1207-
if (textBuffer != null)
1210+
var containedDocument = ContainedDocument.TryGetContainedDocument(documentId);
1211+
if (containedDocument != null)
1212+
{
1213+
containedDocument.UpdateText(newText);
1214+
}
1215+
else
1216+
{
1217+
if (IsDocumentOpen(documentId))
12081218
{
1209-
TextEditApplication.UpdateText(newText, textBuffer, EditOptions.DefaultMinimalChange);
1210-
return;
1219+
var textBuffer = document.GetTextSynchronously(CancellationToken.None).Container.TryGetTextBuffer();
1220+
if (textBuffer != null)
1221+
{
1222+
TextEditApplication.UpdateText(newText, textBuffer, EditOptions.DefaultMinimalChange);
1223+
return;
1224+
}
12111225
}
1212-
}
12131226

1214-
// The document wasn't open in a normal way, so invisible editor time
1215-
using var invisibleEditor = OpenInvisibleEditor(documentId);
1216-
TextEditApplication.UpdateText(newText, invisibleEditor.TextBuffer, EditOptions.None);
1227+
// The document wasn't open in a normal way, so invisible editor time
1228+
using var invisibleEditor = OpenInvisibleEditor(documentId);
1229+
TextEditApplication.UpdateText(newText, invisibleEditor.TextBuffer, EditOptions.None);
1230+
}
12171231
}
1232+
catch (Exception ex) when (FatalError.ReportAndCatch(ex))
1233+
{
1234+
ReportErrorChangingDocumentText(ex);
1235+
return;
1236+
}
1237+
1238+
void ReportErrorChangingDocumentText(Exception exception)
1239+
{
1240+
// Don't spam the info bar. If the user already has a message up, leave it at that. Also,
1241+
// if they've asked to not be notified about future doc change issue, respect that flag.
1242+
if (_ignoreDocumentTextChangeErrors || _isShowingDocumentChangeErrorInfoBar)
1243+
return;
1244+
1245+
var documentName = document?.Name ?? documentId.ToString();
1246+
1247+
var errorReportingService = this.Services.GetRequiredService<IErrorReportingService>();
1248+
errorReportingService.ShowGlobalErrorInfo(
1249+
message: string.Format(ServicesVSResources.Error_encountered_updating_0, documentName),
1250+
TelemetryFeatureName.Workspace,
1251+
exception,
1252+
// 'Show stack trace' will not dismiss the info bar.
1253+
new(WorkspacesResources.Show_Stack_Trace, InfoBarUI.UIKind.HyperLink,
1254+
() => errorReportingService.ShowDetailedErrorInfo(exception), closeAfterAction: false),
1255+
// 'Ignore' just closes the info bar, but allows future errors to show up.
1256+
new(ServicesVSResources.Ignore, InfoBarUI.UIKind.Button, GetDefaultDismissAction()),
1257+
// 'Ignore (including future errors) closes the info bar, but also sets the flag so the user gets no more messages
1258+
// in the current session.
1259+
new(ServicesVSResources.Ignore_including_future_errors, InfoBarUI.UIKind.Button, GetDefaultDismissAction(
1260+
() => _ignoreDocumentTextChangeErrors = true)),
1261+
// Close button is the same as 'ignore'. It closes the info bar, but allows future errors to show up.
1262+
new(string.Empty, InfoBarUI.UIKind.Close, GetDefaultDismissAction()));
1263+
1264+
// Mark that we're showing the info bar at this point.
1265+
_isShowingDocumentChangeErrorInfoBar = true;
1266+
}
1267+
1268+
Action GetDefaultDismissAction(Action? additionalAction = null)
1269+
=> () =>
1270+
{
1271+
additionalAction?.Invoke();
1272+
1273+
// All info bar actions (except for 'show stack trace') dismiss the info bar, putting us back in the
1274+
// "we're not showing the user anything" state.
1275+
_isShowingDocumentChangeErrorInfoBar = false;
1276+
};
12181277
}
12191278

12201279
protected override void ApplyDocumentInfoChanged(DocumentId documentId, DocumentInfo updatedInfo)

src/VisualStudio/Core/Def/ServicesVSResources.resx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,4 +1879,13 @@ Additional information: {1}</value>
18791879
<data name="Show_completion_list_after_a_character_is_typed" xml:space="preserve">
18801880
<value>Show completion list after a character is typed</value>
18811881
</data>
1882+
<data name="Error_encountered_updating_0" xml:space="preserve">
1883+
<value>Error encountered updating '{0}'</value>
1884+
</data>
1885+
<data name="Ignore" xml:space="preserve">
1886+
<value>Ignore</value>
1887+
</data>
1888+
<data name="Ignore_including_future_errors" xml:space="preserve">
1889+
<value>Ignore (including future errors)</value>
1890+
</data>
18821891
</root>

src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)