UNPKG

@duydang2311/attempt

Version:

A functional type for error handling in JS/TS

154 lines (152 loc) 3.37 kB
// lib/pipe.ts function pipe(value, ...fns) { let current = value; for (let i = 0, size = fns.length;i < size; ++i) { current = fns[i](current); if (current instanceof Promise) { return current.then(async (resolved) => { for (let j = i + 1;j < size; ++j) { resolved = fns[j](resolved); if (resolved instanceof Promise) { resolved = await resolved; } } return resolved; }); } } return current; } // lib/attempt.ts function attemptSync(fn) { return (mapException) => { try { return attemptOk(fn()); } catch (e) { return attemptFail(mapException ? mapException(e) : e); } }; } function attemptAsync(fn) { return async (mapException) => { try { const ret = await fn(); if (isAttempt(ret)) { return ret; } return attemptOk(ret); } catch (e) { return attemptFail(mapException ? mapException(e) : e); } }; } function attemptOk(data) { return { ok: true, data, pipe: attemptPipe }; } function attemptFail(error) { return { ok: false, error, pipe: attemptPipe }; } function attemptMap(f) { return (attempt) => { if (!attempt.ok) { return attempt; } const ret = f(attempt.data); if (ret instanceof Promise) { return ret.then(attemptOk); } return attemptOk(ret); }; } function attemptFlatMap(f) { return (attempt) => { if (!attempt.ok) { return attempt; } return f(attempt.data); }; } function attemptMapError(f) { return (attempt) => { if (attempt.ok) { return attempt; } const ret = f(attempt.error); if (ret instanceof Promise) { return ret.then(attemptFail); } return attemptFail(ret); }; } function attemptFlatMapError(f) { return (attempt) => { if (attempt.ok) { return attempt; } return f(attempt.error); }; } function attemptUnwrap(attempt) { if (!attempt.ok) { throw attempt.error; } return attempt.data; } function attemptUnwrapOr(attemptOrDefault, defaultValue) { if (defaultValue) { const attempt = attemptOrDefault; return attempt.ok ? attempt.data : defaultValue; } return (attempt) => attempt.ok ? attempt.data : attemptOrDefault; } function attemptUnwrapOrElse(attemptOrF, f) { if (f) { const attempt = attemptOrF; return attempt.ok ? attempt.data : f(attempt.error); } return (attempt) => attempt.ok ? attempt.data : attemptOrF(attempt.error); } function isAttempt(obj) { return typeof obj === "object" && obj !== null && "ok" in obj && typeof obj.ok === "boolean" && (obj.ok === true && ("data" in obj) || obj.ok === false && ("error" in obj)); } var attempt = { sync: attemptSync, async: attemptAsync, ok: attemptOk, fail: attemptFail, map: attemptMap, flatMap: attemptFlatMap, check: isAttempt, mapError: attemptMapError, flatMapError: attemptFlatMapError, orElse: attemptFlatMapError, unwrap: attemptUnwrap, unwrapOr: attemptUnwrapOr, unwrapOrElse: attemptUnwrapOrElse }; function attemptPipe(...fns) { return pipe(this, ...fns); } export { isAttempt, attemptUnwrapOrElse, attemptUnwrapOr, attemptUnwrap, attemptSync, attemptOk, attemptMapError, attemptMap, attemptFlatMapError, attemptFlatMap, attemptFail, attemptAsync, attempt };