Fix markdown ext errors accessing disposed webview (#149960)

When reloading windows that need to restore a markdown preview, sometimes I'll see an error when the markdown preview tries accessing a disposed of webview. This seems to be cause caused by `provideTextDocumentContent`, where we end up disposing of the webview before an `await` resumes execution
This commit is contained in:
Matt Bierner 2022-05-20 09:17:57 -07:00 committed by GitHub
parent d93881d706
commit 993c36c920
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View file

@ -109,6 +109,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private readonly _onScrollEmitter = this._register(new vscode.EventEmitter<LastScrollLocation>());
public readonly onScroll = this._onScrollEmitter.event;
private readonly _disposeCts = this._register(new vscode.CancellationTokenSource());
constructor(
webview: vscode.WebviewPanel,
resource: vscode.Uri,
@ -202,6 +204,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
}
override dispose() {
this._disposeCts.cancel();
super.dispose();
this._disposed = true;
@ -286,7 +290,9 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
try {
document = await vscode.workspace.openTextDocument(this._resource);
} catch {
await this.showFileNotFoundError();
if (!this._disposed) {
await this.showFileNotFoundError();
}
return;
}
@ -306,7 +312,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
this.currentVersion = pendingVersion;
const content = await (shouldReloadPage
? this._contentProvider.provideTextDocumentContent(document, this, this._previewConfigurations, this.line, this.state)
? this._contentProvider.provideTextDocumentContent(document, this, this._previewConfigurations, this.line, this.state, this._disposeCts.token)
: this._contentProvider.markdownBody(document, this));
// Another call to `doUpdate` may have happened.

View file

@ -66,7 +66,8 @@ export class MarkdownContentProvider {
resourceProvider: WebviewResourceProvider,
previewConfigurations: MarkdownPreviewConfigurationManager,
initialLine: number | undefined = undefined,
state?: any
state: any | undefined,
token: vscode.CancellationToken
): Promise<MarkdownContentProviderOutput> {
const sourceUri = markdownDocument.uri;
const config = previewConfigurations.loadAndCacheConfiguration(sourceUri);
@ -89,6 +90,10 @@ export class MarkdownContentProvider {
const csp = this.getCsp(resourceProvider, sourceUri, nonce);
const body = await this.markdownBody(markdownDocument, resourceProvider);
if (token.isCancellationRequested) {
return { html: '', containingImages: [] };
}
const html = `<!DOCTYPE html>
<html style="${escapeAttribute(this.getSettingsOverrideStyles(config))}">
<head>