show error when inlay hints command fails, annotate error with source (e.g extension name), fixes https://github.com/microsoft/vscode/issues/141588

This commit is contained in:
Johannes Rieken 2022-01-27 10:47:01 +01:00
parent 4f9c9353fb
commit ffdeff7b55
No known key found for this signature in database
GPG key ID: 96634B5AF12F8798
8 changed files with 33 additions and 12 deletions

View file

@ -1846,6 +1846,7 @@ export interface InlayHintList {
}
export interface InlayHintsProvider {
displayName?: string
onDidChangeInlayHints?: Event<void>;
provideInlayHints(model: model.ITextModel, range: Range, token: CancellationToken): ProviderResult<InlayHintList>;
resolveInlayHint?(hint: InlayHint, token: CancellationToken): ProviderResult<InlayHint>;

View file

@ -20,17 +20,17 @@ export class InlayHintItem {
private _isResolved: boolean = false;
private _currentResolve?: Promise<void>;
constructor(readonly hint: InlayHint, readonly anchor: InlayHintAnchor, private readonly _provider: InlayHintsProvider) { }
constructor(readonly hint: InlayHint, readonly anchor: InlayHintAnchor, readonly provider: InlayHintsProvider) { }
with(delta: { anchor: InlayHintAnchor; }): InlayHintItem {
const result = new InlayHintItem(this.hint, delta.anchor, this._provider);
const result = new InlayHintItem(this.hint, delta.anchor, this.provider);
result._isResolved = this._isResolved;
result._currentResolve = this._currentResolve;
return result;
}
async resolve(token: CancellationToken): Promise<void> {
if (typeof this._provider.resolveInlayHint !== 'function') {
if (typeof this.provider.resolveInlayHint !== 'function') {
return;
}
if (this._currentResolve) {
@ -51,7 +51,7 @@ export class InlayHintItem {
private async _doResolve(token: CancellationToken) {
try {
const newHint = await Promise.resolve(this._provider.resolveInlayHint!(this.hint, token));
const newHint = await Promise.resolve(this.provider.resolveInlayHint!(this.hint, token));
this.hint.tooltip = newHint?.tooltip ?? this.hint.tooltip;
this.hint.label = newHint?.label ?? this.hint.label;
this._isResolved = true;

View file

@ -28,7 +28,7 @@ import { goToDefinitionWithLocation, showGoToContextMenu } from 'vs/editor/contr
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import * as colors from 'vs/platform/theme/common/colorRegistry';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
@ -254,7 +254,7 @@ export class InlayHintsController implements IEditorContribution {
}
});
gesture.onCancel(removeHighlight);
gesture.onExecute(e => {
gesture.onExecute(async e => {
const label = this._getInlayHintLabelPart(e);
if (label) {
const part = label.part;
@ -263,7 +263,15 @@ export class InlayHintsController implements IEditorContribution {
this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, part.location);
} else if (languages.Command.is(part.command)) {
// command -> execute it
this._commandService.executeCommand(part.command.id, ...(part.command.arguments ?? [])).catch(err => this._notificationService.error(err));
try {
await this._commandService.executeCommand(part.command.id, ...(part.command.arguments ?? []));
} catch (err) {
this._notificationService.notify({
severity: Severity.Error,
source: label.item.provider.displayName,
message: err
});
}
}
}
});

View file

@ -21,6 +21,7 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
export async function showGoToContextMenu(accessor: ServicesAccessor, editor: ICodeEditor, anchor: HTMLElement, part: RenderedInlayHintLabelPart) {
@ -28,6 +29,7 @@ export async function showGoToContextMenu(accessor: ServicesAccessor, editor: IC
const contextMenuService = accessor.get(IContextMenuService);
const commandService = accessor.get(ICommandService);
const instaService = accessor.get(IInstantiationService);
const notificationService = accessor.get(INotificationService);
await part.item.resolve(CancellationToken.None);
@ -60,8 +62,16 @@ export async function showGoToContextMenu(accessor: ServicesAccessor, editor: IC
if (part.part.command) {
const { command } = part.part;
menuActions.push(new Separator());
menuActions.push(new Action(command.id, command.title, undefined, true, () => {
commandService.executeCommand(command.id, ...(command.arguments ?? []));
menuActions.push(new Action(command.id, command.title, undefined, true, async () => {
try {
await commandService.executeCommand(command.id, ...(command.arguments ?? []));
} catch (err) {
notificationService.notify({
severity: Severity.Error,
source: part.item.provider.displayName,
message: err
});
}
}));
}

1
src/vs/monaco.d.ts vendored
View file

@ -6908,6 +6908,7 @@ declare namespace monaco.languages {
}
export interface InlayHintsProvider {
displayName?: string;
onDidChangeInlayHints?: IEvent<void>;
provideInlayHints(model: editor.ITextModel, range: Range, token: CancellationToken): ProviderResult<InlayHintList>;
resolveInlayHint?(hint: InlayHint, token: CancellationToken): ProviderResult<InlayHint>;

View file

@ -552,8 +552,9 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
// --- inline hints
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined): void {
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined, displayName: string | undefined): void {
const provider = <modes.InlayHintsProvider>{
displayName,
provideInlayHints: async (model: ITextModel, range: EditorRange, token: CancellationToken): Promise<modes.InlayHintList | undefined> => {
const result = await this._proxy.$provideInlayHints(handle, model.uri, range, token);
if (!result) {

View file

@ -441,7 +441,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
$registerSuggestSupport(handle: number, selector: IDocumentFilterDto[], triggerCharacters: string[], supportsResolveDetails: boolean, displayName: string): void;
$registerInlineCompletionsSupport(handle: number, selector: IDocumentFilterDto[]): void;
$registerSignatureHelpProvider(handle: number, selector: IDocumentFilterDto[], metadata: ISignatureHelpProviderMetadataDto): void;
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined): void;
$registerInlayHintsProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean, eventHandle: number | undefined, displayName: string | undefined): void;
$emitInlayHintsEvent(eventHandle: number): void;
$registerDocumentLinkProvider(handle: number, selector: IDocumentFilterDto[], supportsResolve: boolean): void;
$registerDocumentColorProvider(handle: number, selector: IDocumentFilterDto[]): void;

View file

@ -2086,7 +2086,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
const eventHandle = typeof provider.onDidChangeInlayHints === 'function' ? this._nextHandle() : undefined;
const handle = this._addNewAdapter(new InlayHintsAdapter(this._documents, this._commands.converter, provider, this._logService, extension), extension);
this._proxy.$registerInlayHintsProvider(handle, this._transformDocumentSelector(selector), typeof provider.resolveInlayHint === 'function', eventHandle);
this._proxy.$registerInlayHintsProvider(handle, this._transformDocumentSelector(selector), typeof provider.resolveInlayHint === 'function', eventHandle, ExtHostLanguageFeatures._extLabel(extension));
let result = this._createDisposable(handle);
if (eventHandle !== undefined) {