Code Monkey home page Code Monkey logo

pony-cause's Introduction

Pony Cause

Helpers and ponyfill for Error Causes

npm version npm downloads Module type: CJS+ESM Types in JS js-semistandard-style Follow @voxpelli@mastodon.social

Exports

Helpers for working with error causes

All the above are backwards compatible with causes created by the VError module which predated the Error Causes spec and is still used in parts of the ecosystem.

Ponyfill for Error Causes

CJS + ESM + Types

pony-cause is dual published as both CommonJS and ESM, use whichever you like and make use of the TypeScript compliant types no matter which.

Examples

ErrorWithCause

Ponyfill of the cause-supporting Error class

const { ErrorWithCause } = require('pony-cause');

try { /* Something that can break */ } catch (err) {
  throw new ErrorWithCause('Failed doing what I intended', { cause: err });
}

findCauseByReference

Finding an error of a specific type within the cause chain. Is typescript friendly.

const { findCauseByReference } = require('pony-cause');

try { /* Something that can break */ } catch (err) {
  /** @type {MySpecialError} */
  const specialErr = findCauseByReference(err, MySpecialError);

  if (specialErr && specialErr.specialProperty === 'specialValue') {
    // Its okay, chill!
  } else {
    throw err;
  }
}

Used to find a specific type of error in the chain of causes in an error.

Similar to VError.findCauseByName but resolves causes in both Error Causes style, .cause, and VError style, .cause() + takes a reference to the Error class that you are looking for rather than simply the name of it, as that enables the TypeScript types to properly type the returned error, typing it with the same type as the reference.

Can be useful if there's some extra data on it that can help determine whether it's an unexpected error or an error that can be handled.

If it's an error related to a HTTP request, then maybe the request can be retried? If its a database error that tells you about a duplicated row, then maybe you know how to work with that? Maybe forward that error to the user rather than show a 500 error?

Note: findCauseByReference has protection against circular causes

getErrorCause

Getting the direct cause of an error, if there is any

const { getErrorCause } = require('pony-cause');

try { /* Something that can break */ } catch (err) {
  // Returns the Error cause, VError cause or undefined
  const cause = getErrorCause(err);
}

The output is similar to VError.cause() but resolves causes in both Error Causes style, .cause, and VError style, .cause().

Always return an Error, a subclass of Error or undefined. If a cause in Error Causes style cause is not an Error or a subclass of Error, it will be ignored and undefined will be returned.

messageWithCauses

Gets the error message with the messages of its cause chain appended to it.

const { messageWithCauses, ErrorWithCause } = require('pony-cause');

try {
  try {
    // First error...
    throw new Error('First error');
  } catch (err) {
    // ...that's caught and wrapped in a second error
    throw new ErrorWithCause('Second error', { cause: err });
  }
} catch (err) {
  // Logs the full message trail: "Second error: First error"
  console.log(messageWithCauses(err));
}

The output is similar to the standard VError behaviour of appending message with the cause.message, separating the two with a : .

Since Error Causes doesn't do this, messageWithCauses exist to mimic that behaviour.

It respects VError messages, it won't append any error message of their causes, though it will walk past the VError causes to see if there's a non-VError cause up the chain and then append that.

The reason to use this method is explained by VError:

The idea is that each layer in the stack annotates the error with a description of what it was doing. The end result is a message that explains what happened at each level.

If an inner error has a message ENOENT, stat '/nonexistent', an outer error wraps it and adds Can't perform X and maybe one more error wraps that and adds Can't start program, then messageWithCauses will join those three errors together when providing it with the outer most error and return Can't start program: Can't perform X: ENOENT, stat '/nonexistent' which provides details about both cause and effect as well as the connection between the two – each which on their own would be a lot harder to understand the impact of.

Note: messageWithCauses has protection against circular causes

stackWithCauses

Gets a stack trace for the error + all its causes.

const { stackWithCauses } = require('pony-cause');

try { /* Something that can break */ } catch (err) {
  console.log('We had a mishap:', stackWithCauses(err));
}

The output is similar to VError.fullStack() but resolves causes in both Error Causes style, .cause, and VError style, .cause().

Note: stackWithCauses has protection against circular causes

Output looks like:

Error: something really bad happened here
    at Object.<anonymous> (/examples/fullStack.js:5:12)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:968:3
caused by: Error: something bad happened
    at Object.<anonymous> (/examples/fullStack.js:3:12)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:968:3

For enterprise

Available as part of the Tidelift Subscription.

The maintainers of pony-cause and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. Learn more.

Similar modules

  • verror – a module which has long enabled error causes in javascript. Superseded by the new Error Cause proposal. Differs in that.cause represents a function that returns the cause, its not the cause itself.
  • @netflix/nerror – a Netflix fork of verror
  • error-cause – strict polyfill for the Error Cause proposal. Provides no helpers or similar to achieve VError-like functionality, which pony-cause does.

See also

pony-cause's People

Contributors

alessioalex avatar fabiosantoscode avatar renovate-bot avatar renovate[bot] avatar voxpelli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pony-cause's Issues

Ensure `ErrorWithCause` can be subclassed properly with types

The following code gives Type 'unknown' is not assignable to type 'undefined':

import { ErrorWithCause } from 'pony-cause';

class AuthError extends ErrorWithCause {};

try {
  // ...
} catch (err) {
  throw new AuthError('Foobar', { cause: err });
}

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/lint.yml
.github/workflows/nodejs-legacy.yml
.github/workflows/nodejs.yml
.github/workflows/ts-internal.yml
.github/workflows/ts.yml
npm
package.json
  • @types/chai ^4.3.9
  • @types/chai-string ^1.4.4
  • @types/mocha ^10.0.3
  • @types/verror ^1.10.8
  • @voxpelli/eslint-config ^19.0.0
  • @voxpelli/tsconfig ^9.0.0
  • c8 ^8.0.1
  • chai ^4.3.10
  • chai-string ^1.5.0
  • eslint ^8.51.0
  • eslint-plugin-es-x ^7.2.0
  • eslint-plugin-import ^2.28.1
  • eslint-plugin-jsdoc ^46.8.2
  • eslint-plugin-mocha ^10.2.0
  • eslint-plugin-n ^16.2.0
  • eslint-plugin-promise ^6.1.1
  • eslint-plugin-security ^1.7.1
  • eslint-plugin-sort-destructure-keys ^1.5.0
  • eslint-plugin-unicorn ^48.0.1
  • husky ^8.0.3
  • installed-check ^8.0.0
  • knip ^2.35.0
  • linemod ^1.1.0
  • mocha ^10.2.0
  • npm-run-all2 ^6.1.1
  • type-coverage ^2.27.0
  • typescript ~5.2.2
  • verror ^1.10.1
  • node >=12.0.0
test-published-types/package.json

  • Check this box to trigger a request for Renovate to run again on this repository

Fix type regression in `tsnext` which throws `TS2463`

The tsnext tests are now failing: https://github.com/voxpelli/pony-cause/runs/7605089081?check_suite_focus=true

index.js(9,25): error TS2463: A binding pattern parameter cannot be optional in an implementation signature.

Happens at:

/**
* @param {string} message
* @param {{ cause?: T }} [options]
*/
constructor (message, { cause } = {}) {

Likely caused by:

Spontaneous thought is that TS has regressed rather than this being a correct error, but have to dig into it.

TypeScript error

node_modules/pony-cause/index.d.ts:5:5 - error TS2416: Property 'cause' in type 'ErrorWithCause<T>' is not assignable to the same property in base type 'Error'.
  Type 'T' is not assignable to type 'Error | undefined'.
    Type 'T' is not assignable to type 'Error'.

5     cause: T;
      ~~~~~


Found 1 error in node_modules/pony-cause/index.d.ts:

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>whitesource/merge-confidence:beta)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.