throw-on

Throw on console.error() & fetch

Usage no npm install needed!

<script type="module">
  import throwOn from 'https://cdn.skypack.dev/throw-on';
</script>

README

throw-on

npm version Node.js CI Test Coverage Bundle size Prettier Airbnb Code Style

Force console.error and network requests to fail.

  • Tiny: less than 100 lines of code
  • No dependencies
  • Fully tested
  • Written in TypeScript
  • Works with Node.js and browsers
  • Generic: not specific to React

Why?

Do you have warnings like "An update inside a test was not wrapped in act" or "Can't perform a React state update on an unmounted component" when running your React app?

Are your tests performing network requests when they shouldn't?

Solution: throw whenever there is a React warning (e.g. console.error) or a network request that isn't mocked.

  • The sooner a test fails, the easier it is to fix it
  • Improve the quality of your code (like an ESLint rule but at runtime)

Result:

  • before (test passes)

    before

    before

  • after (test fails)

    after

    after

Usage

In your tests

npm install --save-dev throw-on

// Inside jest.setup.js (Jest setupFilesAfterEnv option) for example

import {
  throwOnConsole,
  throwOnFetch,
  throwOnXMLHttpRequestOpen
} from 'throw-on';

throwOnConsole('assert');
throwOnConsole('error');
throwOnConsole('warn');
throwOnFetch();
throwOnXMLHttpRequestOpen();

In the browser

npm install throw-on

// Inside your entry file (something like index.js or app.js)

if (process.env.NODE_ENV !== 'production') { // You probably don't want this in production
  const { throwOnConsole } = await import('throw-on');
  throwOnConsole('assert');
  throwOnConsole('error');
  throwOnConsole('warn');
}

render(<MyApp />, document.getElementById('app'));

Make it your own

Copy-paste throwOnConsole.ts and/or throwOnFetch.ts and/or throwOnXMLHttpRequestOpen.ts into your source code.

Platform support

Requires Node.js >= 15 or a String.replaceAll polyfill.

Transpilation to ES5 (via Babel for example) is needed for non-modern browsers.

API

type Options = {
  /**
   * Messages to ignore (won't throw), each message to ignore can be a substring or a regex.
   *
   * Empty list by default.
   */
  ignore?: (string | RegExp)[];

  /**
   * Displays the full stack trace including the 'throwError()' part if true; this helps for debugging.
   * Works only under V8.
   *
   * False by default.
   */
  fullStackTrace?: boolean;
};

type ConsoleMethodName = 'assert' | 'error' | 'warn' | 'info' | 'log' | 'dir' | 'debug';

/**
 * Makes console method to throw if called.
 */
function throwOnConsole(methodName: ConsoleMethodName, options: Options = {}): void;

/**
 * Restores the original console method implementation.
 */
function restoreConsole(methodName: ConsoleMethodName): void;

/**
 * Makes fetch to throw if called.
 */
function throwOnFetch(): void;

/**
 * Restores the original fetch implementation.
 */
function restoreFetch(): void;

/**
 * Makes XMLHttpRequest.open to throw if called.
 */
function throwOnXMLHttpRequestOpen(): void;

/**
 * Restores the original XMLHttpRequest.open implementation.
 */
function restoreXMLHttpRequestOpen(): void;

Limitations

When using the ignore option, the stack trace displayed by Jest includes an extra line corresponding to throw-on source code. I did not find a solution, here is an attempt: https://github.com/tkrotoff/throw-on/pull/1