tryError Documentation

Advanced
Performance

The Hidden Cost of JavaScript Errors

How tryError can be faster than native try/catch for error handling

The Hidden Cost of Native Errors

When JavaScript throws an error, it always captures a stack trace – even if you never access it. This automatic behavior adds significant overhead that you're paying for whether you need it or not.

What Really Happens When You Catch an Error
The Hidden Workjavascript
try {
  JSON.parse(invalidJson);
} catch (e) {
  // Even if you only use e.message...
  console.log(e.message);
  
  // JavaScript has ALREADY:
  // 1. Captured the full stack trace (expensive!)
  // 2. Parsed the stack into a string
  // 3. Created a full Error object
  // 4. Set up the prototype chain
  
  // All this work happened before you even touched 'e'!
}

Performance Breakdown

Our benchmarks reveal the true cost of JavaScript's automatic error handling:

Benchmark Results (100,000 iterations)
Just catching an error
488ms
Accessing error.message
502ms (+2.9%)
Accessing error.stack
2,870ms (+487%!)

How tryError Beats Native Performance

With minimal configuration, tryError skips all the unnecessary work:

Native try/catch
  • Always captures stack traces
  • Creates full Error objects
  • Parses stack traces to strings
  • No way to opt out
tryError (minimal)
  • No stack trace unless configured
  • Simple objects with only needed data
  • No hidden processing
  • Pay only for what you use

Real-World Example

Here's how to configure tryError for maximum performance in production:

High-Performance Error Handlingtypescript
import { configure, ConfigPresets, trySync } from '@try-error/core';

// Configure for production performance
configure({
  captureStackTrace: false,  // Skip expensive stack traces
  includeSource: false,      // Skip source location detection
  skipTimestamp: false,      // Keep timestamps (cheap)
  skipContext: false,        // Keep context (useful)
  minimalErrors: true        // Use minimal error objects
});

// Or use the preset
configure(ConfigPresets.minimal());

// Now errors are 15% FASTER than native try/catch!
const result = trySync(() => JSON.parse(userInput));

if (isTryError(result)) {
  // Still have everything you need:
  logger.error({
    type: result.type,        // 'SyntaxError'
    message: result.message,  // Full error message
    timestamp: result.timestamp,
    context: result.context
  });
}

When to Use Minimal Configuration

✅ Perfect For:
  • • Production environments where errors are logged elsewhere
  • • High-throughput APIs and services
  • • Validation and parsing operations with expected failures
  • • Serverless functions where every millisecond counts
  • • Any code where you don't need stack traces
❌ Not Ideal For:
  • • Development environments (you want stack traces!)
  • • Debugging complex async operations
  • • When you need to trace error origins
  • • Low-volume applications where performance isn't critical

Summary

tryError isn't just about better error handling – it can actually be faster than native JavaScript error handling.

By understanding that JavaScript automatically captures expensive stack traces for every error (even if unused), we can make informed decisions about when we need this information and when we can skip it for better performance.

The key insight: You should only pay for what you use.