neocities/public/js/monaco/esm/vs/base/common/errors.js

150 lines
4.5 KiB
JavaScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Avoid circular dependency on EventEmitter by implementing a subset of the interface.
export class ErrorHandler {
constructor() {
this.listeners = [];
this.unexpectedErrorHandler = function (e) {
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);
};
}
emit(e) {
this.listeners.forEach((listener) => {
listener(e);
});
}
onUnexpectedError(e) {
this.unexpectedErrorHandler(e);
this.emit(e);
}
// For external errors, we don't want the listeners to be called
onUnexpectedExternalError(e) {
this.unexpectedErrorHandler(e);
}
}
export const errorHandler = new ErrorHandler();
export function onUnexpectedError(e) {
// ignore errors from cancelled promises
if (!isCancellationError(e)) {
errorHandler.onUnexpectedError(e);
}
return undefined;
}
export function onUnexpectedExternalError(e) {
// ignore errors from cancelled promises
if (!isCancellationError(e)) {
errorHandler.onUnexpectedExternalError(e);
}
return undefined;
}
export function transformErrorForSerialization(error) {
if (error instanceof Error) {
const { name, message } = error;
const stack = error.stacktrace || error.stack;
return {
$isError: true,
name,
message,
stack,
noTelemetry: ErrorNoTelemetry.isErrorNoTelemetry(error)
};
}
// return as is
return error;
}
const canceledName = 'Canceled';
/**
* Checks if the given error is a promise in canceled state
*/
export function isCancellationError(error) {
if (error instanceof CancellationError) {
return true;
}
return error instanceof Error && error.name === canceledName && error.message === canceledName;
}
// !!!IMPORTANT!!!
// Do NOT change this class because it is also used as an API-type.
export class CancellationError extends Error {
constructor() {
super(canceledName);
this.name = this.message;
}
}
/**
* @deprecated use {@link CancellationError `new CancellationError()`} instead
*/
export function canceled() {
const error = new Error(canceledName);
error.name = error.message;
return error;
}
export function illegalArgument(name) {
if (name) {
return new Error(`Illegal argument: ${name}`);
}
else {
return new Error('Illegal argument');
}
}
export function illegalState(name) {
if (name) {
return new Error(`Illegal state: ${name}`);
}
else {
return new Error('Illegal state');
}
}
export class NotSupportedError extends Error {
constructor(message) {
super('NotSupported');
if (message) {
this.message = message;
}
}
}
/**
* Error that when thrown won't be logged in telemetry as an unhandled error.
*/
export class ErrorNoTelemetry extends Error {
constructor(msg) {
super(msg);
this.name = 'CodeExpectedError';
}
static fromError(err) {
if (err instanceof ErrorNoTelemetry) {
return err;
}
const result = new ErrorNoTelemetry();
result.message = err.message;
result.stack = err.stack;
return result;
}
static isErrorNoTelemetry(err) {
return err.name === 'CodeExpectedError';
}
}
/**
* 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) {
super(message || 'An unexpected bug occurred.');
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.
// eslint-disable-next-line no-debugger
// debugger;
}
}