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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@yankeeinlondon/kind-error

v2.0.0-beta.1

Published

> A better error primitive for Javascript/Typescript.

Readme

Kind Error

A better error primitive for Javascript/Typescript.

overview diagram

Install

pnpm add @yankeeinlondon/kind-error

| Manager| Shell Command | | --- | --- | | npm | npm install @yankeeinlondon/kind-error | | yarn | yarn add @yankeeinlondon/kind-error | | bun | bun add @yankeeinlondon/kind-error |

Basic Usage

  1. Create an Error type with first call to createKindError:

    const InvalidRequest = createKindError("invalid-request", { 
         lib: "foobar", 
         url: "string", 
         method: "get|post|put|delete|undefined" 
     });

    The error type InvalidRequest has now been created as a KindErrorType:

    • it acts as a function which will produce an error with the following properties:
      • name - the name is the PascalCase version of what you called it (e.g., InvalidRequest)
      • kind - the kind is the kebab-cased version of what you called it (e.g., invalid-request)
      • type - the type is the kind string up to but not including a / character
      • subType - the subType is the kind string after the first / character:
        • if there is no / character in the kind then subType is undefined
        • you may provide a union type for the subType by using the | character:
          • invalid-request/get | post | put | delete
          • will make the subType "get" | "post" | "put" | "delete"
          • when you express the subtype as a union type, this will change the signature of calling this type:
            • The default calling signature is ErrorType(message, props) (where props is potentially optional if there are no required props in the )
      • stackTrace - a structured stack trace for the error
      • Context
        • any properties passed into the second parameter help define the shape of the error
        • In our example:
          • because lib is a non-union string literal it is a fixed property (aka, non-variant) and will always be made available to all errors generated of this time but then creating the error the lib property will not be something you will be allowed to override.
          • the url property is both required and a wide type that means that calling the function will require that the url property be included!
          • the method property is a union and that union type includes undefined as a member so it will be treated as optional parameter to the context.
  2. Creating an Error from an Error Type:

    throw InvalidRequest("oh no!"); // invalid

    Because we defined url as required but gave it a variant type, the syntax above will throw a typescript error and not compile. This mechanism is powerful as it enforces that required properties (which are variant in value) must be included when producing the error.

    throw InvalidRequest("oh no!", { url: "https://google.com" }); // valid

    Now we've addressed the url constraint we optionally can also specify a "method".

    throw InvalidRequest("oh no!", { url: "https://google.com", method: "put" }); // valid

    The type system will require that you use one of the valid values for the method property should you choose to set it.

    throw InvalidRequest("oh no!", { url: "https://google.com", color: "red" }); // invalid

    A KindErrorType is typically strict about the properties it allows for. This means that if you want to add a color property you'd have to have included it in the schema for the error type.

Partial Application

The ability to define an error type with a context schema of key/value pairs to be -- in part -- filled in later when the error is actually being raised is handy because often the details we need to complete an error are only available later. However, to increase flexibility and encourage consistency we must also recognize that sometimes the context we need to report fully on an error is built up in stages over time. This is where the power of partial application comes from.

Let's demonstrate this with an example:

  1. Let's define an error type which immediately sets the lib property but then defines two additional required properties section and url:

    const InvalidRequest = createKindError("invalid-request", { 
        lib: "kind-error", // static property
        section: "one|two|three", // an enumerated set of section choices
        url: "string" // any string value
    });
  2. In our code base we may move into a part of the code where we know the section we're in but the url is still going to be determined later:

    const Err = InvalidRequest.partial({ section: "one" });
  3. Now when we actually want to raise an error we are only presented with the one remaining required property in the context schema url:

    throw Err("This is the error message", { url });

In our example we chose to partially apply a required property of the schema but this will work equally as well with an optional property in the schema too.

Note: at any point when a partial application is done, the key/values applied become a static/readonly part of the context dictionary and future callers will only be required (and able) to modify the key/values which remain as undefined.

Error Proxy

Once you get used to having KindError's there's no going back ... says an entirely unbiased person. But in all seriousness, once you get get used to the strong typing, schema structuring and everything else you find yourself wishing all errors were KindErrors. Well they can be ... in part due to the built-in "proxy" functionality of the KindErrorType.

In the code below we show a standard try/catch block use-case where you might find using the proxy functionality useful:

const Unexpected = createKindError("unexpected");

try {
    // do something dangerous (but exciting)
} catch(e) {
    // Crime never pays, of course you got an error!
    // Hey it's not typed! Should you assume it's supposed to be an `Error`?
    // Who cares, just proxy it.
    throw UnexpectedOutcome.proxy(e, "just in case");
}

Regardless of the underlying shape of e, the proxy function will evaluate it and apply the following logic:

  • if e turns out to be a KindError then the error will be proxied through "as is" (why mess with perfection)
  • if e is just some plain jane Error type then extract the "message" and use it in a Unexpected kind error but add an underlying property which contains the base error.
  • if e is a fetch network response then we'll add both the underlying property and a code property which proxies through the HTTP code returned.
  • if e is a POJO (plain old javascript object) then we'll look for a "message" property and use that for the wrapped kind error's message along with of course adding the underlying property.
  • if e is a string then we'll use that as the kind error's message; no underlying property needed.
  • in all other cases we'll add in the kind error's name in prose format: SomethingBadHappened kind error will be have a message of "Something bad happened".
    • If the user provided a fallback message -- in our example we used just in case -- then we'll use that instead

Type Guards

Type guards are an important part of any good Typescript code. They help us narrow the type at runtime and align the runtime values with the type system so that you can have the strongest benefit of the type system at design time.

This library provides several type guards which you can use to help on your next project.

Detecting Errors

  1. isOk(val) - tests whether value is any recognized form of Error or RequestFailure and if it is not excludes these error types from val's type.
  2. isError(val) - tests whether val is any recognized form of an Error or RequestFailure and isolates the type of val to only these types.
  3. isKindError(val, [kind]) - this type guard will establish whether the variable val is a valid KindError or not. You can also optionally specify a particular 'kind' you want to look for.
  4. KindErrorType.is(val) - every KindErrorType error type comes with a is(val) type guard built in.

Used in Error Proxy

We also expose some type guards which we internally use as part of the proxy functionality but you may find use for this too (and hey, sharing is caring):

  1. isFetchResponse(val)
  2. isFetchError(val)
  3. isStringifyable(val)

Structured Callstack and Pretty Print

The two major entity types defined in this repo are KindErrorType (a error type) and KindError (an error) and both come with built-in toString() functions which produce nice looking console output when converted to a string. WIth the KindError this output is aided by a structured call stack which is parsed from Javascript's string stack property and provided (if you want direct access) to the stackTrace property on kind errors.

As an example, when you have something like the following code: console.log(InvalidType), you'll get something resembling this in your console:

example stack trace output