src/vs/base/common/errors.ts
357 LOC · 288 covered · 69 uncovered · 69 ranges · 20961 concepts · 24 introducers · 12741 tests
File neighbourhood
The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.
Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.
/*---------------------------------------------------------------------------------------------
map.ts ×97
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export interface ErrorListenerCallback {
(error: any): void;
}
export interface ErrorListenerUnbind {
(): void;
}
// Avoid circular dependency on EventEmitter by implementing a subset of the interface.
export class ErrorHandler {
private unexpectedErrorHandler: (e: any) => void;
private listeners: ErrorListenerCallback[];
constructor() {
this.listeners = [];
this.unexpectedErrorHandler = function (e: any) {
setTimeout(() => {
if (e.stack) {
if (ErrorNoTelemetry.isErrorNoTelemetry(e)) {
throw new ErrorNoTelemetry(e.message + '\n\n' + e.stack);
}
throw new Error(e.message + '\n\n' + e.stack);
}
throw e;
}, 0);
};
addListener(listener: ErrorListenerCallback): ErrorListenerUnbind {
return () => {
this._removeListener(listener);
};
private emit(e: any): void {
}
private _removeListener(listener: ErrorListenerCallback): void {
this.listeners.splice(this.listeners.indexOf(listener), 1);
}
setUnexpectedErrorHandler(newUnexpectedErrorHandler: (e: any) => void): void {
this.unexpectedErrorHandler = newUnexpectedErrorHandler;
}
getUnexpectedErrorHandler(): (e: any) => void {
}
onUnexpectedError(e: any): void {
this.emit(e);
}
// For external errors, we don't want the listeners to be called
onUnexpectedExternalError(e: any): void {
this.unexpectedErrorHandler(e);
}
export const errorHandler = new ErrorHandler();
/** @skipMangle */
export function setUnexpectedErrorHandler(newUnexpectedErrorHandler: (e: any) => void): void {
errorHandler.setUnexpectedErrorHandler(newUnexpectedErrorHandler);
}
/**
* Returns if the error is a SIGPIPE error. SIGPIPE errors should generally be
* logged at most once, to avoid a loop.
*
* @see https://github.com/microsoft/vscode-remote-release/issues/6481
*/
export function isSigPipeError(e: unknown): e is Error {
if (!e || typeof e !== 'object') {
return false;
}
const cast = e as Record<string, string | undefined>;
return cast.code === 'EPIPE' && cast.syscall?.toUpperCase() === 'WRITE';
}
/**
* This function should only be called with errors that indicate a bug in the product.
* E.g. buggy extensions/invalid user-input/network issues should not be able to trigger this code path.
* If they are, this indicates there is also a bug in the product.
*/
export function onBugIndicatingError(e: any): undefined {
return undefined;
}
export function onUnexpectedError(e: any): undefined {
if (!isCancellationError(e)) {
errorHandler.onUnexpectedError(e);
}
return undefined;
}
export function onUnexpectedExternalError(e: any): undefined {
// ignore errors from cancelled promises
if (!isCancellationError(e)) {
errorHandler.onUnexpectedExternalError(e);
}
return undefined;
}
type ObjectWithCode = {
readonly code: unknown;
};
return Object.hasOwn(error, 'code');
}
export function getErrorCode(error: unknown): string | undefined {
return undefined;
}
return typeof code === 'string' || typeof code === 'number' ? String(code) : undefined;
errors.ts ×3
}
export interface SerializedError {
readonly $isError: true;
readonly name: string;
readonly message: string;
readonly stack: string;
readonly noTelemetry: boolean;
readonly code?: string;
readonly cause?: SerializedError;
}
type ErrorWithCode = Error & {
code: string | undefined;
};
export function transformErrorForSerialization(error: Error): SerializedError;
export function transformErrorForSerialization(error: any): any;
export function transformErrorForSerialization(error: any): any {
// eslint-disable-next-line local/code-no-any-casts
const stack: string = (<any>error).stacktrace || (<any>error).stack;
return {
$isError: true,
name,
message,
stack,
noTelemetry: ErrorNoTelemetry.isErrorNoTelemetry(error),
cause: cause ? transformErrorForSerialization(cause) : undefined,
code: (<ErrorWithCode>error).code
};
}
// return as is
return error;
}
export function transformErrorFromSerialization(data: SerializedError): Error {
if (data.noTelemetry) {
error = new ErrorNoTelemetry();
error = new Error();
error.name = data.name;
}
error.message = data.message;
error.stack = data.stack;
if (data.code) {
(<ErrorWithCode>error).code = data.code;
}
}
}
// see https://github.com/v8/v8/wiki/Stack%20Trace%20API#basic-stack-traces
export interface V8CallSite {
getThis(): unknown;
getTypeName(): string | null;
getFunction(): Function | undefined;
getFunctionName(): string | null;
getMethodName(): string | null;
getFileName(): string | null;
getLineNumber(): number | null;
getColumnNumber(): number | null;
getEvalOrigin(): string | undefined;
isToplevel(): boolean;
isEval(): boolean;
isNative(): boolean;
isConstructor(): boolean;
toString(): string;
}
export const canceledName = 'Canceled';
/**
* Checks if the given error is a promise in canceled state
*/
export function isCancellationError(error: any): boolean {
}
return error instanceof Error && error.name === canceledName && error.message === canceledName;
errors.ts ×2
}
// !!!IMPORTANT!!!
// Do NOT change this class because it is also used as an API-type.
export class CancellationError extends Error {
constructor() {
this.name = this.message;
}
export class PendingMigrationError extends Error {
private static readonly _name = 'PendingMigrationError';
static is(error: unknown): error is PendingMigrationError {
return error instanceof PendingMigrationError || (error instanceof Error && error.name === PendingMigrationError._name);
extensionHostMain.ts ×5
}
constructor(message: string) {
super(message);
this.name = PendingMigrationError._name;
}
/**
* @deprecated use {@link CancellationError `new CancellationError()`} instead
*/
export function canceled(): Error {
error.name = error.message;
return error;
}
export function illegalArgument(name?: string): Error {
if (name) {
return new Error(`Illegal argument: ${name}`);
} else {
return new Error('Illegal argument');
}
}
export function illegalState(name?: string): Error {
return new Error(`Illegal state: ${name}`);
} else {
return new Error('Illegal state');
}
export class ReadonlyError extends TypeError {
constructor(name?: string) {
super(name ? `${name} is read-only and cannot be changed` : 'Cannot change read-only property');
errors.ts ×1
}
export function getErrorMessage(err: any): string {
return 'Error';
}
if (err.message) {
return err.message;
}
if (err.stack) {
return err.stack.split('\n')[0];
}
return String(err);
}
export class NotImplementedError extends Error {
constructor(message?: string) {
super('NotImplemented');
if (message) {
this.message = message;
}
}
export class NotSupportedError extends Error {
constructor(message?: string) {
super('NotSupported');
if (message) {
this.message = message;
}
}
export class ExpectedError extends Error {
readonly isExpected = true;
/**
* Error that when thrown won't be logged in telemetry as an unhandled error.
*/
export class ErrorNoTelemetry extends Error {
override readonly name: string;
constructor(msg?: string) {
this.name = 'CodeExpectedError';
}
public static fromError(err: Error): ErrorNoTelemetry {
if (err instanceof ErrorNoTelemetry) {
return err;
}
const result = new ErrorNoTelemetry();
result.message = err.message;
result.stack = err.stack;
return result;
}
public static isErrorNoTelemetry(err: Error): err is ErrorNoTelemetry {
}
/**
* This error indicates a bug.
* Do not throw this for invalid user input.
* Only catch this error to recover gracefully from bugs.
*/
export class BugIndicatingError extends Error {
constructor(message?: string) {
Object.setPrototypeOf(this, BugIndicatingError.prototype);
// Because we know for sure only buggy code throws this,
// we definitely want to break here and fix the bug.
// debugger;
}