@nodecg/types
Version:
Dynamic broadcast graphics rendered in a browser
70 lines (65 loc) • 1.96 kB
text/typescript
/**
* Make a string out of an error (or other equivalents),
* including any additional data such as stack trace if available.
* Safe to use on unknown inputs.
*/
export function stringifyError(error: unknown, noStack = false): string {
const o = stringifyErrorInner(error);
if (noStack || !o.stack) {
return o.message;
}
return `${o.message}, ${o.stack}`;
}
export function stringifyErrorInner(error: unknown): {
message: string;
stack: string | undefined;
} {
let message: string | undefined;
let stack: string | undefined;
if (typeof error === "string") {
message = error;
} else if (error === null) {
message = "null";
} else if (error === undefined) {
message = "undefined";
} else if (error && typeof error === "object") {
if (
typeof (error as any).error === "object" &&
(error as any).error.message
) {
message = (error as any).error.message;
stack = (error as any).error.stack;
} else if ((error as any).reason) {
if ((error as any).reason.message) {
message = (error as any).reason.message;
stack = (error as any).reason.stack || (error as any).reason.reason;
} else {
// Is a Meteor.Error
message = (error as any).reason;
stack = (error as Error).stack;
}
} else if ((error as Error).message) {
// Is an Error
message = (error as Error).message;
stack = (error as Error).stack;
} else if ((error as any).details) {
message = (error as any).details;
} else {
try {
// Try to stringify the object:
message = JSON.stringify(error);
} catch (e: unknown) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
message = `${error} (stringifyError: ${e})`;
}
}
} else {
// eslint-disable-next-line @typescript-eslint/no-base-to-string,@typescript-eslint/restrict-template-expressions
message = `${error}`;
}
message = `${message}`;
return {
message,
stack,
};
}