Package Exports
- pcall.js
Readme

Ƥ𝖢𐤠LL.ᴊꜱ
Result/Monad like tuples for JS
unwrap promises safely with minimum footprint
── ╶╴╶╴╶╴╶╴╶╴╶╴╶╴ ──
🧬 Lifecycle Hooks
📦 Zero Dependency
🎯 Concise Signature
💠 Group Side Effects
⛔ try/catch HELL 👹
🌟 Better Visibility and Control
🌐 Works in ESM & CJS
✱ Minimal Obsessive Disorder
Inspiration
pcall.js
is heavily inspired by
🔹 Lua pcall
status, res
🔹 Elixir/Erlang Result Monad {:ok/:error, reason/value}
🔹 Rust Result<T, E>
🔹 Go []error
with superpowers 🦄!
In Lua Errors are detected and explained in terms of Lua. ^Lua:5.4 ^Lua:8.4, ^Lua:8.5
You can contrast that with C, where the behavior of many wrong programs can only be explained in terms of the underling hardware and error positions are given as a program counter
Activities start from a call by the application, usually asking to run a chunk.
If there is any error, this call returns an error code and the application can take appropriate actions
SYNOPSIS
pcall({f}, {arg1}, {...})
pcall()
Calls function {f}
with the given arguments in protected mode.
This means that any error inside {f}
is not propagated;
Instead, pcall
catches the error and returns a tuple.
Its first element is the error code status code (a boolean),
Which is false
if the call succeeds without errors.
And all results from the call, on second element; [false, {res}]
In case of any error,
Pcall returns true
plus the error message; [true, {err}]
Usage
# install
npm install pcall.js
// ESM
import Pcall from 'pcall.js'
// CJS
const Pcall = require('pcall.js')
Convert
import { readFile } from 'node:fs/promises'
// 🔻 BEFORE
try {
const res = await readFile('./package.json', { encoding: 'utf8' })
} catch(error) {
console.error(error, '🔥')
}
// ─────────────────
// 🔹AFTER
import Pcall from 'pcall.js'
const [err, res] = await Pcall(readFile, './package.json', { encoding: 'utf8' })
// 🔸THROW
err && throw new Error("XYZZY", { cause: err });
// ─────────────────
// 🔸 NO @ITERATOR
import Pcall from 'pcall.js'
const pcall = new Pcall({ noError: true })
const res = await pcall(readFile, './package.json', { encoding: 'utf8' })
// ─────────────────
// 🔸 MOCK
const readJson = new Pcall({
fn: readFile,
noError: true,
args: [{ encoding: 'utf8' }],
transformOnSuccess: (args, res) => JSON.parse(res),
transformOnFailure: (args, { name, message }) => ({ name, message }),
})
const path = 'test/sample-good.json'
const res = await readJson(path)
log(res.hogo) // fuga
Options
import { readFile } from 'node:fs/promises'
import Pcall from 'pcall.js'
const pcall = new Pcall({
onSuccess: console.log,
onFailure: console.error,
onFinally: (args, func, span) => { /* 💣 💣 💥 */ },
transformOnSuccess: (args, res) => res,
transformOnFailure: (args, err) => err,
timeout: 60_000,
noError: false,
noTrace: false,
})
const path = './package.json'
const opts = { encoding: 'utf8' }
const [err, res] = await pcall(readFile, path, opts)
💡 Check test/ files for more examples
Development
# run test playground in watch mode
npm run dev
# build production
npm run build
# build stub
npm run build:stub
TODO
- 🌀 Lifecycle Hooks
- [.] 🔌 Serializer
- [.] 🧬 Parser
- [.] 📜 JSDoc
- [.] 🔧 ESLint
- [o] 📖 Docs
- [o] ⚠️ Tests
- [.] 💡 Examples