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

uncatch

v1.0.4

Published

Global uncaught exception handler

Downloads

3,007

Readme

Overview

Uncatch is a cooperative uncaught exception manager, which allows multiple modules to register listeners for uncaught exceptions, and all of them will be executed before the process finally exits. The module also handles emitting the error and stack trace to STDERR.

As of v1.0.3, Uncatch also treats all unhandled rejections as if they were unhandled exceptions. This is the default behavior in Node.js v15+ anyway, and it allows both of these events to be handled in the same cooperative way in older Node.js versions.

Why

The reason for this module is that Node.js behaves differently when you register an uncaught exception handler. If any listeners are defined for this global event, then the stack trace is no longer emitted to the console, and the process does not exit. It is up to your listener code to handle both operations. This is bad because multiple modules may all want to execute their own emergency shutdown / cleanup code, especially in larger applications, but if any of them were to call process.exit() (as they should) then not all the listeners get a chance to execute.

Uncatch solves this problem by offering its own global EventEmitter upon which multiple modules may all register listeners. Uncatch then registers a single global uncaught exception handler and fires its own uncaughtException event, executing all of its listeners before finally emitting the error and stack trace to STDERR, and calling process.exit(1).

All modules in your application have to agree to use Uncatch for this to really work. If any module in your stack registers a global uncaught exception handler and calls process.exit() then all bets are off.

Use Case

Imagine a modular Node.js daemon application that spawns and manages child processes. If the root daemon suffers an uncaught exception, it should kill off its children as it goes down. This is fine, but what happens when it adds a global uncaught exception handler? That handler needs to call process.exit() as per best practices, but then no other modules can do anything. For example, the application may have another module that also needs to perform shutdown operations, like logging the exception to a crash log, etc.

If your application can manage this from a single global uncaught exception handler, then you probably don't need Uncatch. But if you have a modular application where multiple separate modules all need to cooperate to run multiple shutdown operations, with a single exit at the very end, then Uncatch may be for you.

Related Modules

What about the uncaught module? This module came close to what I needed, but it doesn't emit the error and stack trace to STDERR, and it doesn't call process.exit() after all its listeners execute.

What about the uncaught-exception module? It has weird requirements, seems to be built around statsd, its usage is confusing, and the README says things like "v0.10 only". It rubbed me the wrong way.

What about the exception module? This module is rather nifty, but it doesn't solve the problem where multiple modules all need to run uncaught exception code. Also, it has native module requirements (like heapdump).

Usage

Download via npm:

npm install uncatch --save

Use it in your modules like this:

const Uncatch = require('uncatch');

Uncatch.on('uncaughtException', function(err) {
	// execute your own application shutdown routine here
	// do not call any async code, and do not call process.exit
});

//
// ...in some other module...
//

const Uncatch = require('uncatch');

Uncatch.on('uncaughtException', function(err) {
	// this code will ALSO run!
});

You do not have to call process.exit() as Uncatch will do it for you, once all the event listeners are executed. If you need to log the crash, use synchronous filesystem operations like fs.appendFileSync(). Nothing async will execute. It's sync or die during a crash.

Custom Exit Code

By default Uncatch calls process.exit(1) which signals an unclean exit to whatever calling process or shell spawned your Node.js app. You can change this exit code by setting Uncatch.exitCode. You can even do this from inside an uncaught exception listener. Example:

Uncatch.on('uncaughtException', function(err) {
	// change exit code
	Uncatch.exitCode = 65;
});

Please note that the latter prevails here. If multiple modules all fight to customize the exitCode then whichever one did it last is the winner.

Environment Variables

Uncatch recognizes the following environment variables, if they are set to any true value:

| Variable | Description | |----------|-------------| | NO_UNCATCH | If set, do not register an uncaught exception handler. | | NO_UNERROR | If set, do not emit the error and stack trace to STDERR. | | NO_UNEXIT | If set, do not call process.exit(). WARNING: Don't do this. Here's why. |

For example, to temporarily disable Uncatch, run your app thusly:

NO_UNCATCH=1 node your-app.js

License

The MIT License (MIT)

Copyright (c) 2017 - 2024 Joseph Huckaby

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.