@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
114 lines (113 loc) • 3.57 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports._try = _try;
exports.pTry = pTry;
exports._expectedError = _expectedError;
exports.pExpectedError = pExpectedError;
exports.pExpectedErrorString = pExpectedErrorString;
exports._expectedErrorString = _expectedErrorString;
const stringify_1 = require("../string/stringify");
const assert_1 = require("./assert");
const error_util_1 = require("./error.util");
/**
* Calls a function, returns a Tuple of [error, value].
* Allows to write shorter code that avoids `try/catch`.
* Useful e.g. in unit tests.
*
* Similar to pTry, but for sync functions.
*
* ERR is typed as Error, not `unknown`. While unknown would be more correct,
* according to recent TypeScript, Error gives more developer convenience.
* In our code we NEVER throw non-errors.
* Only possibility of non-error is in the 3rd-party library code, in these cases it
* can be manually cast to `unknown` for extra safety.
*
* @example
*
* const [err, v] = _try(() => someFunction())
* if (err) ...do something...
* v // go ahead and use v
*/
function _try(fn, errorClass) {
try {
return [null, fn()];
}
catch (err) {
if (errorClass) {
(0, assert_1._assertErrorClassOrRethrow)(err, errorClass);
}
return [err, null];
}
}
/**
* Like _try, but for Promises.
*/
async function pTry(promise, errorClass) {
try {
return [null, await promise];
}
catch (err) {
if (errorClass) {
(0, assert_1._assertErrorClassOrRethrow)(err, errorClass);
}
return [err, null];
}
}
/**
* Calls `fn`, expects is to throw, catches the expected error and returns.
* If error was NOT thrown - throws UnexpectedPassError instead.
*
* If `errorClass` is passed:
* 1. It automatically infers it's type
* 2. It does `instanceof` check and throws if wrong Error instance was thrown.
*/
function _expectedError(fn, errorClass) {
try {
fn();
}
catch (err) {
if (errorClass && !(err instanceof errorClass)) {
console.warn(`_expectedError expected ${errorClass.constructor.name} but got different error class`);
throw err;
}
return err; // this is expected!
}
// Unexpected!
throw new error_util_1.UnexpectedPassError();
}
/**
* Awaits passed `promise`, expects is to throw (reject), catches the expected error and returns.
* If error was NOT thrown - throws UnexpectedPassError instead.
*
* If `errorClass` is passed:
* 1. It automatically infers it's type
* 2. It does `instanceof` check and throws if wrong Error instance was thrown.
*/
async function pExpectedError(promise, errorClass) {
try {
await promise;
}
catch (err) {
if (errorClass && !(err instanceof errorClass)) {
console.warn(`pExpectedError expected ${errorClass.constructor.name} but got different error class`);
throw err;
}
return err; // this is expected!
}
// Unexpected!
throw new error_util_1.UnexpectedPassError();
}
/**
* Shortcut function to simplify error snapshot-matching in tests.
*/
async function pExpectedErrorString(promise, errorClass) {
const err = await pExpectedError(promise, errorClass);
return (0, stringify_1._stringify)(err);
}
/**
* Shortcut function to simplify error snapshot-matching in tests.
*/
function _expectedErrorString(fn, errorClass) {
const err = _expectedError(fn, errorClass);
return (0, stringify_1._stringify)(err);
}