
Security News
New CNA Scorecard Tool Ranks CVE Data Quality Across the Ecosystem
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.
do-try-tuple
Advanced tools
Catches errors and rejected promises, returns tuple with error and value.
npm install do-try-tuple
import doTry from 'do-try-tuple';
function div(a: number, b: number): number {
if (b !== 0) return a / b;
if (a !== 0) throw new Error(`Division by Zero`);
throw new Error('Indeterminate Form');
}
const [isDivOk, errX, x] = doTry(() => div(4, 2));
if (isDivOk) {
const doubleX = x * 2;
console.log('doubleX:', doubleX);
}
import doTry from 'do-try-tuple';
const [areUsersFetched, error, users] = await doTry(() => fetchUsers());
if (!areUsersFetched) {
console.error('Failed to fetch users:', error);
} else {
console.log('Users:', users);
}
or
import { safe } from 'do-try-tuple';
const [areUsersFetched, error, users] = await safe(fetchUsers());
if (!areUsersFetched) {
console.error('Failed to fetch users:', error);
} else {
console.log('Users:', users);
}
The library exports:
doTry
function (default export)safe
promise wrapper to make it resolving to ErrValueTuple
Failure
, Success
and ErrValueTuple
typesfailure
and success
factory functionsisFailure
and isSuccess
type guardsdoTry
functiontakes a function that may throw an error or return a promise that may be rejected.
function (fn: () => never): readonly [false, unknown, never];
function (fn: () => Promise<never>): Promise<readonly [false, unknown, never]>;
function <T>(fn: () => Promise<T>): Promise<ErrValueTuple<T>>;
function <T>(fn: () => T): ErrValueTuple<T>;
safe
promise wrapperis a function that wraps a promise and makes it resolving to ErrValueTuple
:
function safe<T>(promise: Promise<T>): Promise<ErrValueTuple<T>>;
It could be useful when you need to handle the promise rejection synchronously:
import { safe } from 'do-try-tuple';
const [areUsersFatched, error, users] = await safe(fetchUsers());
Failure
typeis a tuple representing the error case:
export type Failure<E = unknown> = readonly [ok: false, error: E, value: undefined];
The library respects the same motivation as caused introduction useUnknownInCatchVariables compiler option in TypeScript:
Success
typeis a tuple representing the success case:
export type Success<T> = readonly [ok: true, error: undefined, value: T];
ErrValueTuple
typeis a union of Failure<E>
and Success<T>
.
export type ErrValueTuple<T, E = unknown> = Failure<E> | Success<T>;
failure
and success
factory functionsThese functions allow to create ErrValueTuple
instances:
export function failure<E>(error: E): Failure<E>;
export function success<T>(value: T): Success<T>;
It could be useful in tests:
import { success, failure } from 'do-try-tuple';
test('div', () => {
expect(doTry(() => div(4, 2))).toEqual(success(2));
expect(doTry(() => div(4, 0))).toEqual(failure(new Error('Division by Zero')));
expect(doTry(() => div(0, 0))).toEqual(failure(new Error('Indeterminate Form')));
});
isFailure
and isSuccess
type guardsThese functions allow to check if the value is Failure
or Success
:
export function isFailure(value: ErrValueTuple<unknown>): value is Failure;
export function isSuccess(value: ErrValueTuple<unknown>): value is Success<unknown>;
It allows to check the result and narrow the type without destructuring:
class DivError extends Error {
constructor(message: string) {
super(message);
this.name = 'DivError';
}
}
function divWithTypeError(a: number, b: number): ErrValueTuple<number, DivError> {
const result = doTry(() => div(a, b));
if (isSuccess(result)) return result;
return failure(new DivError('Failed to divide'));
}
doTry().then()
You can map the result of doTry
applied to function returning a promise using then
method:
import doTry from 'do-try-tuple';
const [error, users] = await doTry(() => fetchUsers()).then(
([err, users]) => [err && new SomeCustomError(err), users] as const,
);
However, consider that functions returning promises can throw error synchronously:
const fetchUsers = (): Promise<string[]> => {
if (Math.random() < 0.5) throw new Error('Failed to fetch users');
return Promise.resolve(['Alice', 'Bob', 'Charlie']);
};
So, the doTry
in this case returns an ErrValueTuple
synchronously, and the
attempt to call then
method on it will throw an error:
TypeError: doTry(...).then is not a function
.
To handle this case, just add async
keyword before fn
argument:
const [error, users] = await doTry(async () => fetchUsers()).then(
([err, users]) => [err && new SomeCustomError(err), users] as const,
);
So, use
// CORRECT _____
const [err, value] = await doTry(async () => someFn(...))
.then(([err, value]) => {
// handle err and value
});
instead of
// WRONG ___________
const [err, value] = await doTry(/* async */() => someFn(...))
.then(([err, value]) => {
// handle err and value
});
The same is relevant for any other method of Promise
class, like catch
, finally
, etc.
FAQs
Catches errors and rejected promises, returns tuple
The npm package do-try-tuple receives a total of 387 weekly downloads. As such, do-try-tuple popularity was classified as not popular.
We found that do-try-tuple demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The CNA Scorecard ranks CVE issuers by data completeness, revealing major gaps in patch info and software identifiers across thousands of vulnerabilities.
Research
/Security News
Two npm packages masquerading as WhatsApp developer libraries include a kill switch that deletes all files if the phone number isn’t whitelisted.
Research
/Security News
Socket uncovered 11 malicious Go packages using obfuscated loaders to fetch and execute second-stage payloads via C2 domains.