2 years ago

#40544

test-img

SILENT

NodeJS: Is there still a performance penalty to throwing Errors?

Depending on the nodejs framework, there are usually two ways to manage errors.

  • Throw them (ie throw new Error('invalid id');)
  • Return them (ie return { 400: 'invalid id' };)

Due to old advice that throwing errors is inefficient, I always tried to return errors but I prefer throwing errors since they are more convenient. The only article referring to the performance hit was referring to Node v0.

Is it still true?


Update 1

Nvm, I realized I could test it myself. Following code is for reference:

import { performance } from "perf_hooks";

function ThrowException() {
    throw new Error("invalid exception");
}
const _ATTEMPT = 1000000;
function ThrowingExceptions() {
    const p1 = performance.now();
    for (let i = 0; i < _ATTEMPT; i++) {
        try {
            ThrowException();
        } catch (ex: any) {
            // log error
        }
    }
    const p2 = performance.now();
    console.log(`ThrowingExceptions: ${p2 - p1}`);
}
function ReturnException() {
    return { error: { _: "invalid exception" } };
}
function ReturningExceptions() {
    const p1 = performance.now();
    for (let i = 0; i < _ATTEMPT; i++) {
        const ex = ReturnException();
        if (ex.error) {
            // log error
        }
    }
    const p2 = performance.now();
    console.log(`ReturningExceptions: ${p2 - p1}`);
}

function Process() {
    ThrowingExceptions();
    ReturningExceptions();
    ThrowingExceptions();
    ReturningExceptions();
}

Process();

Results

ThrowingExceptions: 15961.33209991455
ReturningExceptions: 5.09220027923584
ThrowingExceptions: 16461.43380022049
ReturningExceptions: 3.0963997840881348

Update 2

Creating errors created the largest penalty. Thanks @Bergi

import { performance } from "perf_hooks";

const error = new Error("invalid exception");
function ThrowException() {
    throw error;
}
const _ATTEMPT = 1000000;
function ThrowingExceptions() {
    const p1 = performance.now();
    for (let i = 0; i < _ATTEMPT; i++) {
        try {
            ThrowException();
        } catch (ex: any) {
            // log error
        }
    }
    const p2 = performance.now();
    console.log(`ThrowingExceptions: ${p2 - p1}`);
}
function ReturnException() {
    return { error };
}
function ReturningExceptions() {
    const p1 = performance.now();
    for (let i = 0; i < _ATTEMPT; i++) {
        const ex = ReturnException();
        if (ex.error) {
            // log error
        }
    }
    const p2 = performance.now();
    console.log(`ReturningExceptions: ${p2 - p1}`);
}

function Process() {
    ThrowingExceptions();
    ReturningExceptions();
    ThrowingExceptions();
    ReturningExceptions();
}

Process();

Results

ThrowingExceptions: 2897.1585998535156
ReturningExceptions: 3.7821998596191406
ThrowingExceptions: 2905.3162999153137
ReturningExceptions: 4.0701003074646

javascript

node.js

exception

try-catch

throw

0 Answers

Your Answer

Accepted video resources