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

async-unwrap

v1.1.0

Published

Simple tool to avoid try-catch blocks

Downloads

17

Readme

Async-await can help you write some amazing-looking and very readable code, but if you're anything like me, you probably hate burying it into try-catch blocks. With async-unwrap, you can go from this:

async () => {
  try {
    await someAsyncOperation()
  } catch (err) {
    doSomething(err)
  }
}

to this:

async () => {
  const [err, result] = await someAsyncOperation()[unwrap]
  if (err) return doSomething(err)
}

But how?

First, you need to say the magic word:

const unwrap = require('async-unwrap')
// or if the above is way too old for you:
import unwrap from 'async-unwrap'

This gives you a symbol that's attached to the prototype of every promise (or other thenable), which turns that promise into another one. The "unwrapped" promise will resolve to a ~~tuple~~ two-element array of [null, result] if the base promise is resolved and [err, null] if it's rejected. This allows you to handle your errors in a slightly different way, without breaking the block scope.

If you're using multiple async calls in a function, I'd recommend structuring your code in the following way:

async () => {
  const [firstError, firstResult] = await firstOperation()[unwrap]
  if (firstError) throw firstError // we'll handle it on a higher level

  const [secondError, secondResult] = await secondOperation(firstResult)[unwrap]
  if (secondError) throw sanitize(secondError) // sometimes you'll need some special treatment

  return secondResult
}

Exercise to the reader: try writing that without nested try-catch blocks or falling back to let.

Local offensive

Before you ask, yes, that does modify global variables, specifically Object.prototype, which is actually the variable you should have the most caution with modifying. async-unwrap uses a symbol to define a non-enumerable getter, minimizing the surface for errors (it's practically invisible in normal usage), but in some exotic cases you might still run into problems with that. If you'd like to not take that chance, there is a "function" variant of the library:

import unwrap from 'async-unwrap/func'

async () => {
  const [err, result] = await unwrap(someAsyncOperation())
  if (err) return doSomething(err)
}

Why is this not the default? Well, frankly because I think it's ugly, but to each their own. You can use the function variant if you'd like to, no hard feelings.

Compatibility

Everything, theoretically. The library binds to all objects and simply checks for a then() method, which is the JS spec's way of deciding if something is a promise. This should enable it to work seamlessly with custom promise implementations. If you still run into any compatibility issues, please submit a bug report.

Contributing

Pull requests are welcome. As always, be respectful towards each other and maybe run or create tests, as appropriate. It's on npm test, as usual.

async-unwrap is available under the MIT license.