Skip to main content
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Dave Ferguson and Simon Free and Tim Cunningham and Jason Dean
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Dave Ferguson ( @dfgrumpy ) Simon Free ( @simonfree ) Tim Cunningham ( @TimCunningham71 ) Jason Dean ( @JasonPDean )

Rethrowing Errors In JavaScript And Node.js

By on

When dealing with errors, handling them at the perimeter of your application isn't always sufficient. By the time the error bubbles up, you've often lost a lot of the context in which the error was thrown. As such, people will sometimes catch an error, record it locally in some way, and then rethrow it. In ColdFusion, we use the rethrow() function. But, in JavaScript and Node.js, there is no rethrow() function; instead, you just throw() the original error object.

This works in both JavaScript (in general) and in Node.js. But, for the context of the demo, I'll be running my code in Node.js where I can require my custom error object. In the following code, I'll be throwing an error in one method, catching it and rethrowing it in another method, and then finally catching it in yet another method:

// Require our core application modules.
var appError = require( "./app-error" ).createAppError;


// Start a method chain that will throw an error:
// --> foo() [catches error]
// -----> bar() [catches / rethrows error]
// --------> baz() [throws error]
foo();


function foo() {

	try {

		bar();

	} catch ( error ) {

		console.log( "Error caught in Foo():", error.message );
		console.log( error.stack );

	}

}


function bar() {

	// In this case, we are going to catch any errors thrown by baz(), log them to the
	// console, and then rethrow them.
	try {

		baz();

	} catch ( error ) {

		console.log( "Error caught and rethrown in Bar():", error.message );

		// In JavaScript, there is no special "rethrow" keyword. You simply throw() the
		// error that you caught. This will maintain the original stacktrace recorded by
		// the error as you "pass it back up" the call-stack.
		throw( error );

	}

}


function baz() {

	throw(
		appError({
			type: "App.CustomError",
			message: "Something went wrong in baz().",
			detail: "Testing errors and rethrowing in JavaScript and Node.js."
		})
	);

}

As you can see, the error, thrown in baz() was rethrown in bar(). And, yet, when the error is finally caught in foo(), we get the following terminal output:

Rethrowing error objects in JavaScript and Node.js.

As you can see from the stacktrace, the error caught in foo() was the same error thrown in baz() and then rethrown in bar().

Rethrowing errors is a great way to inspect [and log] an error locally but defer the handling of it to a point higher up in the call-stack. Of course, having a rich, robust error object is also great for this. I'm just happy that this approach works in JavaScript and Node.js as well as other programming languages, like ColdFusion.

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel