@zerothrow/core
Version:
Core ZeroThrow functionality - Rust-style Result<T,E> for TypeScript
131 lines (128 loc) • 3.94 kB
JavaScript
;
// src/error.ts
var ZeroError = class _ZeroError extends Error {
code;
context;
constructor(code, message, opts = {}) {
super(message, { cause: opts.cause });
this.code = code;
this.context = opts.context;
this.name = "ZeroError";
Object.setPrototypeOf(this, new.target.prototype);
}
/**
* Override toString to include full error chain with context
*/
toString() {
let result = `${this.name} [${String(this.code)}]: ${this.message}`;
if (this.context && Object.keys(this.context).length > 0) {
result += `
Context: ${JSON.stringify(this.context, null, 2).replace(/\n/g, "\n ")}`;
}
let currentCause = this.cause;
let depth = 1;
while (currentCause instanceof Error) {
const indent = " ".repeat(depth);
const causeName = currentCause.name || "Error";
result += `
${indent}Caused by: ${causeName}: ${currentCause.message}`;
if (currentCause instanceof _ZeroError && currentCause.context) {
const contextStr = JSON.stringify(
currentCause.context,
null,
2
).replace(/\n/g, `
${indent} `);
result += `
${indent} Context: ${contextStr}`;
}
currentCause = currentCause.cause;
depth++;
}
return result;
}
/**
* Get the full stack trace including all causes
*/
getFullStack() {
let fullStack = this.stack || "";
let currentCause = this.cause;
while (currentCause instanceof Error) {
fullStack += "\n\nCaused by:\n" + (currentCause.stack || currentCause.toString());
currentCause = currentCause.cause;
}
return fullStack;
}
};
// src/result.ts
function createResult(base) {
const result = base;
result.andThen = function(fn) {
if (!result.ok) return createResult({ ok: false, error: result.error });
return fn(result.value);
};
result.mapErr = function(fn) {
if (result.ok) return createResult({ ok: true, value: result.value });
return createResult({ ok: false, error: fn(result.error) });
};
result.map = function(fn) {
if (!result.ok) return createResult({ ok: false, error: result.error });
return createResult({ ok: true, value: fn(result.value) });
};
result.orElse = function(fallback) {
if (result.ok) return result;
return fallback();
};
result.unwrapOr = function(fallback) {
return result.ok ? result.value : fallback;
};
result.unwrapOrThrow = function() {
if (!result.ok) throw result.error;
return result.value;
};
result.tap = function(fn) {
if (result.ok) fn(result.value);
return result;
};
result.tapErr = function(fn) {
if (!result.ok) fn(result.error);
return result;
};
result.finally = function(fn) {
if (result.ok) fn(result.value);
else fn();
return result;
};
result.void = function() {
if (!result.ok) return createResult({ ok: false, error: result.error });
return createResult({ ok: true, value: void 0 });
};
return result;
}
var ok = (value) => createResult({ ok: true, value });
var err = (error) => createResult({ ok: false, error });
var normalise = (e) => {
if (e instanceof ZeroError) return e;
if (e instanceof Error) {
if ("code" in e && typeof e.code === "string" && "context" in e) {
return e;
}
return new ZeroError("UNKNOWN_ERR", e.message, { cause: e });
}
return new ZeroError("UNKNOWN_ERR", String(e));
};
function wrap(cause, code, msg, ctx) {
const errorCode = code ?? (cause instanceof ZeroError ? cause.code : "code" in cause && cause.code ? cause.code : "WRAPPED_ERROR");
const message = msg ?? cause.message;
return new ZeroError(errorCode, message, {
cause,
...ctx !== void 0 && { context: ctx }
});
}
exports.ZeroError = ZeroError;
exports.err = err;
exports.normalise = normalise;
exports.ok = ok;
exports.wrap = wrap;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map