npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eslint-plugin-no-throw-await

v1.0.0

Published

Forces explicit error handling for promises (Similar to golang) through disallowing unpredictable awaits.

Downloads

6

Readme

eslint-plugin-no-throw-await

Forces explicit error handling for promises (Similar to golang) through disallowing unpredictable awaits

Why?

await can't be trusted. and try-catching everything is 💩. Explicit error handling is the way. It doesn't clutter your code it makes it better. Take a look at the following code:

async function foo() {
    await bar()
}

Is bar safe to await? does it throw an exception maybe? Just in case let's wrap it in a try-catch

async function foo() {
    try {
        await bar()
    } catch (e) {
        /* whatever */
    }
}

Now assume you don't know what foo does. Or you don't want to read every async function line by line to check if it may throw an exception before using it. So what do you do? Also wrap foo in a try-catch just in case

try { await foo() } catch (e) { }

When/how do you propgate an error to the caller? or do you silence everything throuh a try catch? What if you have a series of async functions. But you don't want one throw to stop everything. Do you just wrap every single one in a try-catch. Or worse, use .catch for a quick nesting hell trip. There are many other examples of how bad this trycatching can get, amongst other issues with throwing in an async func.

The goal of this plugin is to treat every promise as unsafe, which they are, and only allow awaiting a safe promise. A safe promise in this case means one that will not crash the application if left outside of a try-catch (will never throw). To to that, a linter rule will prevent you from awaiting a promise unless it's wrapped by an awaitable function.

awaitable

Turns any unsafe promise into safe promise. One implementation (golang like error handling):

/**
 * Guarantees that a promise throw will be handled and returned gracefully as an error if any
 * The returned promise will never throw an exception
 * Result and error type can be specified through awaitable<ResultType, ErrorType>
 * @param fn Promise
 * @returns Promise<[result, error]>
 * - `result`: Returned on success, null on throw (Infered type of `fn`)
 * - `error`: Null on success, returned on throw (Default to Error)
 */
/* Modified version from karanpratapsingh */
async function awaitable<R, E = Error> (
  fn: Promise<R>
): Promise<[R | null, E | null]> {
  try {
    // eslint-disable-next-line no-throw-await/no-direct-await
    const data: R = await fn
    return [data, null]
  } catch (error: any) {
    return [null, error]
  }
}

Example

async function foo (): Promise<boolean> {
  throw new Error('Some error')
}

async function testing (): Promise<void> {
  const [result, err] = await awaitable(foo())
  if (err != null) {
    console.log(err.message)
    return
  }

  // Do stuff with result
  console.log(result)
}

Installation

You'll first need to install ESLint:

npm i eslint --save-dev

Next, install eslint-plugin-no-throw-await:

npm install eslint-plugin-no-throw-await --save-dev

Usage

Add no-throw-await to the plugins section of your .eslintrc configuration file. You can omit the eslint-plugin- prefix:

{
    "plugins": [
        "no-throw-await"
    ]
}

Then configure the rule under the rules section.

{
    "rules": {
        "no-throw-await/no-direct-await": "error"
    }
}

Rules

🔧 Automatically fixable by the --fix CLI option.
💡 Manually fixable by editor suggestions.

| Name | Description | 🔧 | 💡 | | :----------------------------------------------- | :------------------------------------------------- | :- | :- | | no-direct-await | Enforces using an await handler before every await | 🔧 | 💡 |