UNPKG

@naturalcycles/js-lib

Version:

Standard library for universal (browser + Node.js) javascript

114 lines (113 loc) 3.57 kB
"use strict"; 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); }