UNPKG

lib-result

Version:

A Rust-inspired `Result` type for type-safe error handling in TypeScript and JavaScript

192 lines (189 loc) 3.79 kB
// src/utils.ts function toError(e) { if (e instanceof Error) return e; if (typeof e === "string") return new Error(e); if (isKeyValue(e)) return createCustomError(e); return new Error("Unknown error"); } function isKeyValue(value) { return typeof value === "object" && value !== null && !Array.isArray(value); } function createCustomError(props) { const error = new Error(props?.message || "Unknown Error"); if (isKeyValue(props)) { return Object.assign(error, props); } return error; } // src/mixens.ts var methodsArray = [ withIsOk, withIsError, withUnwrap, withExpect, withMap, withPipe, withMatch, withOrElse, withUnwrapOr ]; function compose(base, ...fns) { return Object.freeze(fns.reduce((obj, fn) => fn(obj), base)); } function withIsOk(base) { return Object.assign(base, { isOk() { return this.error === void 0; } }); } function withIsError(base) { return Object.assign(base, { isError() { return this.error !== void 0; } }); } function withUnwrap(base) { return Object.assign(base, { unwrap() { if (this.isOk()) return this.ok; throw this.error; } }); } function withExpect(base) { return Object.assign(base, { expect(message) { if (this.isOk()) return this.ok; throw createCustomError({ message, cause: this.error }); } }); } function withMap(base) { return Object.assign(base, { map(fn) { try { if (this.isOk()) return Ok(fn(this.ok)); } catch (e) { return Err(toError(e)); } return Err(this.error); } }); } function withPipe(base) { return Object.assign(base, { pipe(fn) { try { if (this.isOk()) return fn(this.ok); } catch (e) { return Err(toError(e)); } return Err(this.error); } }); } function withMatch(base) { return Object.assign(base, { match(okFn, errFn) { try { if (this.isOk()) return okFn(this.ok); return errFn(this.error); } catch (e) { return errFn(toError(e)); } } }); } function withOrElse(base) { return Object.assign(base, { orElse(errFn) { try { if (this.isOk()) return this.ok; return errFn(this.error); } catch (e) { throw toError(e); } } }); } function withUnwrapOr(base) { return Object.assign(base, { unwrapOr(fallback) { return this.isOk() ? this.ok : fallback; } }); } function Ok(ok) { return compose({ ok, error: void 0 }, ...methodsArray); } function Err(error) { if (!(error instanceof Error)) { throw new TypeError( "Err expects an Error instance, use ErrFromObject instead." ); } return compose({ ok: void 0, error }, ...methodsArray); } function ErrFromText(message) { return compose( { ok: void 0, error: new Error(message) }, ...methodsArray ); } function ErrFromObject(props) { return compose( { ok: void 0, error: createCustomError(props) }, ...methodsArray ); } // src/main.ts function wrap(callback) { try { return Ok(callback()); } catch (error) { return Err(toError(error)); } } async function wrapAsync(callback) { try { return Ok(await callback()); } catch (error) { return Err(toError(error)); } } function wrapThrowable(callback) { return (...args) => { try { return Ok(callback(...args)); } catch (e) { return Err(toError(e)); } }; } function wrapAsyncThrowable(callback) { return async (...args) => { try { return Ok(await callback(...args)); } catch (e) { return Err(toError(e)); } }; } export { Err, ErrFromObject, ErrFromText, Ok, wrap, wrapAsync, wrapAsyncThrowable, wrapThrowable };