skip to content
Andrei Calazans

Why Predefining Errors as Constants is Problematic

/ 1 min read

Using predefined error constants like const VALIDATION_ERROR = new Error('Invalid input'); may seem convenient, but it introduces misleading stack traces, which can complicate debugging and error tracking.

The Issue: Misleading Stack Traces

When you create an error object, its stack trace is captured at the point of instantiation. If you reuse a predefined error, its stack trace points to where it was defined, not where it was thrown.

const VALIDATION_ERROR = new Error('Invalid input');

function validateInput(input) {
  if (typeof input !== 'string') {
    throw VALIDATION_ERROR; // Stack trace points to definition, not here
  }
}

This makes it harder to locate the actual cause of the error.

Better Approach: Create Errors Dynamically

To ensure accurate stack traces, instantiate the error when throwing it:

function validateInput(input) {
  if (typeof input !== 'string') {
    throw new Error('Invalid input'); // Stack trace points here
  }
}

For reusable error messages, use an error factory:

function createValidationError(message) {
  return new Error(message);
}

Why It Matters

  • Accurate Debugging: Stack traces point to the actual problem.
  • Better Tool Integration: Tools like Bugsnag and Sentry rely on correct stack traces.
  • Clarity: Makes finding and fixing issues faster and easier.

Avoid predefined errors to simplify debugging and improve maintainability.