Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
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 [errX, x] = doTry(() => div(4, 2));
if (errX == null) {
const doubleX = x * 2;
console.log('doubleX:', doubleX);
}
import doTry from 'do-try-tuple';
const [error, users] = await doTry(() => fetchUsers());
if (error != null) {
console.error('Failed to fetch users:', error);
} else {
console.log('Users:', users);
}
The library exports:
doTry
function (default export)ErrValueTuple
typeUnknownError
typesuccess
and failure
constructor functionsDoTryError
classDoTryErrorCode
type and constantsdoTry
functiontakes a function that may throw an error or return a promise that may be rejected.
function doTry(fn: () => never): [UnknownError, never];
function doTry(fn: () => Promise<never>): Promise<[UnknownError, never]>;
function doTry<T>(fn: () => T): ErrValueTuple<T>;
function doTry<T>(fn: () => Promise<T>): Promise<ErrValueTuple<T>>;
ErrValueTuple
typeis a union of two tuples: one representing the error case and the other representing the success case.
export type ErrValueTuple<T> =
| [UnknownError, undefined] // error case
| [undefined, T]; // success case
UnknownError
typetype represents an unknown, non-nullish value caught by doTry
function.
export type UnknownError = NonNullable<unknown>; // actually it is a {} type
In case when doTry
catches null
or undefined
value, it returns a DoTryError
as the first item of the tuple.
The library respects the same motivation as caused introduction useUnknownInCatchVariables compiler option in TypeScript:
Error
classsuccess
and failure
constructor functionsThese functions allow to create ErrValueTuple
instances:
export function success<T>(value: T): Readonly<[undefined, T]>;
export function failure(error: UnknownError): Readonly<[UnknownError, undefined]>;
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')));
});
DoTryError
classis an error class that is returned when doTry
cannot comply to the ErrValueTuple
contract:
fn
argument is not a functionnull
or undefined
null
or undefined
valueexport class DoTryError extends Error {
constructor(code: DoTryErrorCode, cause: unknown);
}
Fields:
Field | Type | Description |
---|---|---|
message | string | error message |
code | DoTryErrorCode | error code |
cause | unknown | caught error (null or undefined ) or fn argument |
DoTryErrorCode
type and constantsis an union of string literal error codes that DoTryError
class uses.
Code / Instance Of | Description | Cause |
---|---|---|
code: 'ERR_NOT_A_FUNCTION' class: DoTryError.NotAFunction | fn argument is not a function | fn |
code: 'ERR_NULLISH_VALUE_REJECTED' class: DoTryError.NullishValueRejected | promise returned by fn is rejected with null or undefined value | caught value |
code: 'ERR_NULLISH_VALUE_THROWN' class: DoTryError.NullishValueThrown | fn throws null or undefined value | caught value |
ErrValueTuple
To discriminate the ErrValueTuple
type, you should compare the first element of the tuple to
undefined
. The most concise way to do that is to use the != null
expression:
const [err, value] = doTry(() => someFn(...someArgs));
if (err != null) {
// handle error
return;
}
// handle value
The most performant way is to use strict equality comparison:
const [err, value] = doTry(() => someFn(...someArgs));
if (err !== undefined) {
// handle error
return;
}
// handle value
if (error)
or if (!error)
to discriminate the tupleThe if (error)
expression will not work as expected in else
block, because if
casts
err
to boolean
type and narrows its type in then
-branch correctly, but in else
-branch
the type of err
is still UnknownError | undefined
, so TypeScript
cannot discriminate
the ErrValueTuple
type correctly:
const [error, value] = doTry(() => someFn(...someArgs));
if (error) {
// handle error
return;
}
// value is still of type `T | undefined`
// error is still of type `UnknownError | undefined`
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 3 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 1 open source maintainer 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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.