Add JSError renderer, experiment with NotebookCellOutputItem#error-factory function, https://github.com/microsoft/vscode/issues/120063

This commit is contained in:
Johannes Rieken 2021-05-12 16:11:19 +02:00
parent 64e707842e
commit 39ee13c839
No known key found for this signature in database
GPG key ID: 96634B5AF12F8798
4 changed files with 76 additions and 0 deletions

View file

@ -1271,9 +1271,17 @@ declare module 'vscode' {
// static textplain(value:string): NotebookCellOutputItem;
// static errortrace(value:any): NotebookCellOutputItem;
/**
* Creates `application/x.notebook.error`
*
* @param err An error for which an output item is wanted
*/
static error(err: Error): NotebookCellOutputItem;
mime: string;
//todo@API string or Unit8Array?
// value: string | Uint8Array | unknown;
value: unknown;
metadata?: { [key: string]: any };

View file

@ -3087,6 +3087,13 @@ export class NotebookCellOutputItem {
return typeof (<vscode.NotebookCellOutputItem>obj).mime === 'string';
}
static error(err: Error): NotebookCellOutputItem {
return new NotebookCellOutputItem(
'application/x.notebook.error',
JSON.stringify({ name: err.name, message: err.message, stack: err.stack })
);
}
constructor(
public mime: string,
public value: unknown, // JSON'able

View file

@ -14,6 +14,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { handleANSIOutput } from 'vs/workbench/contrib/debug/browser/debugANSIHandling';
@ -277,6 +278,64 @@ class ErrorRendererContrib extends Disposable implements IOutputRendererContribu
}
}
class JSErrorRendererContrib implements IOutputRendererContribution {
constructor(
public notebookEditor: ICommonNotebookEditor,
@IThemeService private readonly _themeService: IThemeService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ILogService private readonly _logService: ILogService,
) { }
dispose(): void {
// nothing
}
getType() {
return RenderOutputType.Mainframe;
}
getMimetypes() {
return ['application/x.notebook.error'];
}
render(_output: ICellOutputViewModel, items: IOutputItemDto[], container: HTMLElement, _notebookUri: URI): IRenderOutput {
const linkDetector = this._instantiationService.createInstance(LinkDetector);
for (let item of items) {
if (typeof item.value !== 'string') {
this._logService.warn('INVALID output item (not a string)', item.value);
continue;
}
let err: Error;
try {
err = <Error>JSON.parse(item.value);
} catch (e) {
this._logService.warn('INVALID output item (failed to parse)', e);
continue;
}
const header = document.createElement('div');
const headerMessage = err.name && err.message ? `${err.name}: ${err.message}` : err.name || err.message;
if (headerMessage) {
header.innerText = headerMessage;
container.appendChild(header);
}
const stack = document.createElement('pre');
stack.classList.add('traceback');
if (err.stack) {
stack.appendChild(handleANSIOutput(err.stack, linkDetector, this._themeService, undefined));
}
container.appendChild(stack);
container.classList.add('error');
}
return { type: RenderOutputType.Mainframe };
}
}
class PlainTextRendererContrib extends Disposable implements IOutputRendererContribution {
getType() {
return RenderOutputType.Mainframe;
@ -459,6 +518,7 @@ NotebookRegistry.registerOutputTransform('jpeg', JPEGRendererContrib);
NotebookRegistry.registerOutputTransform('plain', PlainTextRendererContrib);
NotebookRegistry.registerOutputTransform('code', CodeRendererContrib);
NotebookRegistry.registerOutputTransform('error-trace', ErrorRendererContrib);
NotebookRegistry.registerOutputTransform('jserror', JSErrorRendererContrib);
NotebookRegistry.registerOutputTransform('stream-text', StreamRendererContrib);
NotebookRegistry.registerOutputTransform('stderr', StderrRendererContrib);

View file

@ -551,6 +551,7 @@ const _mimeTypeInfo = new Map<string, MimeTypeInfo>([
['image/jpeg', { supportedByCore: true }],
['text/x-javascript', { alwaysSecure: true, supportedByCore: true }], // secure because rendered as text, not executed
['application/x.notebook.error-traceback', { alwaysSecure: true, supportedByCore: true }],
['application/x.notebook.error', { alwaysSecure: true, supportedByCore: true }],
['application/x.notebook.stream', { alwaysSecure: true, supportedByCore: true, mergeable: true }],
['application/x.notebook.stdout', { alwaysSecure: true, supportedByCore: true, mergeable: true }],
['application/x.notebook.stderr', { alwaysSecure: true, supportedByCore: true, mergeable: true }],