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

p-flat

v0.2.0

Published

Go inspired error handling for asynchronous functions.

Downloads

10

Readme

p-flat

Go inspired error handling for asynchronous functions.

Installation

npm install p-flat

yarn add p-flat

pnpm add p-flat

Example Usage

import p from "p-flat";

const [res, err] = await p(someAsyncWork(...args));

if (err !== null) {
  // If `err` is not `null`, some error or value has been thrown
  // `res` will be `null` and cannot be used safely here
  // Error handling for `someAsyncWork` should be done here
  console.error(err);
  return;
}

// Else, `res` will be the correct return type and value of `someAsyncWork`
console.log(res);
  • If err is not null (ie. the asynchronous function threw an error), then res will be null
  • If err is null (ie. the asynchronous function did not throw any errors), then res is guaranteed to have the return type and value of the resolved function

Rationale

Inspired from the error handling in Go, this construct greatly increases code readability.

As an example, let's say we have these two asynchronous function:

async function getRandomNumber(): Promise<number> {
  const randomNumber = await api.random();
  return randomNumber;
}

async function getSquareNumber(x: number): Promise<number> {
  const squareNumber = await api.square(x);
  return squareNumber;
}

Assume api is a class which handles asynchronous API calls to an external service which may occasionally throw an error. If we first want to get a random number, followed by getting the square of it, we can do the following without any error handling:

const randomNumber = await getRandomNumber();
const squareNumber = await getSquareNumber(randomNumber);
// Continue execution with `squareNumber`

If we want to handle the errors separately, two different try-catch blocks must be added:

let randomNumber: number;
try {
  randomNumber = await getRandomNumber();
} catch (error) {
  console.error(error);
}

let squareNumber: number;
try {
  squareNumber = await getSquareNumber(randomNumber);
} catch (error) {
  console.error(error);
}

// Continue execution with `squareNumber`

Or alternatively, with callbacks:

const randomNumber = await getRandomNumber().catch(
  (error) => console.error
);
const squareNumber = await getSquareNumber(randomNumber).catch(
  (error) => console.error
);

// Continue execution with `squareNumber`

Both implementations are less than ideal. The try-catch version is excessively verbose and requires the use of the mutable let declarations. The callback version, though more concise, has no elegant way to stop execution if the asynchronous functions throw any errors.

With p-flat:

const [randomNumber, randomNumberErr] = await p(getRandomNumber());
if (randomNumberErr !== null) {
  console.error(randomNumberErr);
  // Uncomment the next line to stop execution
  // return;
}

const [squareNumber, squareNumberErr] = await p(getSquareNumber(randomNumber));
if (squareNumberErr !== null) {
  console.error(squareNumberErr);
  // Uncomment the next line to stop execution
  // return;
}

// Continue execution with `squareNumber`