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

eor

v0.2.0

Published

Eor is a try-catch wrapper that returns an [error, data] tuple.

Downloads

9

Readme

eor

Eor is a strongly-typed try-catch wrapper library that makes trying and catching easier to work with. It comes with two functions, eor, and nor.

npm install eor
import { eor } from 'eor'

let [err, num] = eor(() => 1) // => [null, 1]
let [err, num] = eor(() => {
  throw 'bad'
}) // => ['bad', null]
import { nor } from 'eor'

let num = nor(() => 1) // => 1
let num = nor(() => {
  throw 'bad'
}) // => null

Explanation

Try-catch code is noisy and hard to work with. This is a recipe for bugs. Simplifying the interface will lead to that is easier to read and reason about. With nor you get the simplest experience: you either get the return value, or you get null.

const x = nor(() => 1) // => 1
const y = nor(() => {
  throw 'bad'
}) // => null

With eor you get more to work with, in that the return value is wrapped in an error-data tuple, which lets you use the error value in your control-flow.

import { eor } from 'eor'

let [err, num] = eor(() => 1) // => [null, 1]
let [err, num] = eor(() => {
  throw 'bad'
}) // => ['bad', null]

Tutorials

Query Params to Database Query

Let's say you are passing query params to a database query (safely!). You don't know ahead of time whether the id provided in the query param exists. Your database library throws when it fails to find the row. Also, all of this is asynchronous.

First, install eor npm i eor. Then wrap your database call in eor. queryParamId might be undefined, or it might be defined and not exist, both of which will cause our database library to throw.

import { eor } from 'eor'
import { db } from 'db-library'

// assume the db-library throws the following strings when it throws.
function get(queryParamId) {
  const [e, data] = await eor(() => db.get(queryParamId))
  if (e === 'id is undefined') {
    return 500
  } else if (e === 'id does not exist') {
    return 400
  }

  return data
}

Alternatively, with nor you can simply try to get the data, and bail on failure.

import { nor } from 'eor'
import { db } from 'db-library'

function get(queryParamId) {
  const data = await nor(() => db.get(queryParamId))
  return data ? data : 404
}

Delicate Calculator

Let's say you are working with a library that performs a delicate and complicated calculation. You want to take user input and try to perform the calculation.

First, install eor npm i eor. Then, wrap the calculation in eor. If it is successful we will return the results, otherwise we will log the error as a warning and return the error value in case a function upstream wants to work with it.

import { eor } from 'eor'
import { calculator } from 'delicate-complicated-library'

function safeCalculator(userInput1, userInput2) {
  const [e, results] = eor(() => calculator(userInput1, userInput2))
  if (results) return results
  console.warn(e)
  return e
}

If we didn't care about the errors coming from the library itself, we could instead use nor.

import { nor } from 'eor'
import { calculator } from 'delicate-complicated-library'

function safeCalculator(userInput1, userInput2) {
  const results = nor(() => calculator(userInput1, userInput2))
  if (results) return results
  console.warn('calculation failed!')
}

How-To Guides

Work with Error-Data Tuples

function mightThrow() {
  // code which might throw...
}

function bad(e) {
  // what to do when `mightThrow` throws...
}

function good(data) {
  // what to do when `mightThrow` returns data...
}

function f() {
  const [e, data] = eor(mightThrow)
  if (e) return bad(e)
  return good(data)
}

Working with functions with parameters

You can call functions with parameters by wrapping it in a higher-order function with no parameters.

const a = 1
const b = 2
const multiParameterFunction = (a, b) => a + b
const x = nor(() => multiParameterFunction(a, b))
// x === 3

Reference

eor

eor stands for "Error OR". It has one parameter, either a function with no parameters, or a Promise. In all cases it will try to return the results. If it succeeds, for return type R, it returns [null, R]. If it fails, it returns [any, null], where any is the returned error value.

Synchronous Functions

const [e, num] = eor(() => 1) // => [null, 1]
const [e, num] = eor(() => {
  throw 'bad'
}) // => ['bad', null]

Asynchronous Functions

async function fetchData {
  // async stuff...
  return 1
}
const [e, num] = await eor(fetchData) // => [null, 1]
async function fetchData {
  throw 'bad'
}
const [e, num] = await eor(fetchData) // => ['bad', null]

Promise

const p = Promise.resolve(1)
const [e, num] = await eor(p) // => [null, 1]
const p = Promise.reject('bad')
const [e, num] = await eor(p) // => ['bad', 1]

nor

nor stands for "Null OR". It has one parameter, either a function with no parameters, or a Promise. In all cases it will try to return the results. If it succeeds, for return type R, it returns R. If it fails, it returns null.

Synchronous Functions

const num = nor(() => 1) // => 1
const num = nor(() => {
  throw 'bad'
}) // => null

Asynchronous Functions

async function fetchData {
  // async stuff...
  return 1
}
const num = await nor(fetchData) // => 1
async function fetchData {
  throw 'bad'
}
const num = await nor(fetchData) // => null

Promise

const p = Promise.resolve(1)
const num = await nor(p) // => 1
const p = Promise.reject('bad')
const num = await nor(p) // => null