brilliant-errors
Version:
A set of configurators to help your Apps and Libraries build brilliant error classes
125 lines (112 loc) • 4 kB
JavaScript
// src/@guards/index.ts
function isBrilliantError(error) {
return error instanceof Error && error.kind === "BrilliantError";
}
// src/@types/BaseBrilliance.ts
var BaseBrilliance = class extends Error {
constructor() {
super(...arguments);
this.kind = "BrilliantError";
}
};
// src/configurators/createError.ts
import callsites from "callsites";
// src/shared/prettyStack.ts
function prettyStack(s) {
return s.map((i) => {
const file = (i.getFileName() || "[file unknown]").split("/").slice(-2).join("/");
const func = i.getFunctionName() || i.getMethodName() || "unknown";
const line = i.getLineNumber();
return ` - ${file}, ${func}()${line ? `, at line ${line}` : ""}`;
}).join("\n");
}
// src/configurators/constructors/standard.ts
var standard_default = (ctx, props) => (message, classification, options) => {
ctx.message = `[ ${classification} ]: ${message}
${prettyStack(ctx.structuredStack)}`;
ctx.classification = classification;
const parts = classification.split("/");
ctx.code = parts[0];
ctx.subType = parts[1];
if (options?.httpStatusCode || props.configOptions.defaultHttpStatus) {
ctx.httpStatus = options?.httpStatusCode || props.configOptions.defaultHttpStatus;
}
};
// src/configurators/constructors/wrapper.ts
var wrapper_default = (ctx, _props) => (underlying, classification, options) => {
ctx.classification = classification;
if (options?.httpErrorCode) {
ctx.httpStatus = options.httpErrorCode;
}
ctx.message = options?.message ? `${options?.message} [ ${classification} ]: ${underlying.message}
${prettyStack(
ctx.structuredStack
)}` : `${underlying.message} [ ${classification} ]: wrapped error ${underlying.name}
${prettyStack(ctx.structuredStack)}`;
ctx.structuredStack = [];
};
// src/configurators/constructors/network.ts
var network_default = (ctx, props) => (code, message, options) => {
ctx.httpStatus = code;
const classification = options?.classification || `${props.configOptions.defaultType || props.app}/${props.configOptions.defaultSubType} || "unspecified"`;
ctx.classification = classification;
ctx.message = `${message} [ ${code}, ${classification} ]
${prettyStack(
ctx.structuredStack
)}`;
};
// src/configurators/constructors/index.ts
var constructors_default = (ctx, props) => ({
standard: standard_default(ctx, props),
wrapper: wrapper_default(ctx, props),
network: network_default(ctx, props)
});
// src/configurators/createError.ts
var createError = (name, app) => (...types) => (...subTypes) => (...httpCodes) => (configOptions) => {
const ErrorClass = class BrilliantError extends Error {
constructor(...params) {
super("");
this.kind = "BrilliantError";
this.constructorType = configOptions?.constructorType || "standard";
this.name = name;
this.app = app;
this.structuredStack = callsites().slice(1) || [];
this.filename = (this.structuredStack[0].getFileName() || "").split("/").slice(-2).join("/");
this.line = this.structuredStack[0].getLineNumber();
this.fn = this.structuredStack[0].getMethodName() || this.structuredStack[0].getFunctionName();
const c = constructors_default(this, {
name,
app,
types,
subTypes,
httpCodes,
configOptions: configOptions || {}
});
const ctor = c[this.constructorType];
ctor(...params);
}
toJSON() {
return {
app: this.app,
name: this.name,
message: this.message,
classification: this.classification,
httpStatus: this.httpStatus,
code: this.code,
subType: this.subType,
fn: this.fn,
line: this.line
};
}
};
const SpecificGuard = (unknown) => {
return isBrilliantError(unknown) && unknown.name === name && unknown.app === app;
};
return [ErrorClass, SpecificGuard, isBrilliantError];
};
export {
BaseBrilliance,
createError,
isBrilliantError,
prettyStack
};