Back to all reviewers

Wrap throwing operations

cloudflare/workerd
Based on 3 comments
TypeScript

Always wrap potentially throwing operations in try/catch blocks to prevent unhandled exceptions from crashing the application or causing unexpected behavior. This includes property access on unknown objects, API calls, and resource initialization.

Error Handling TypeScript

Reviewer Prompt

Always wrap potentially throwing operations in try/catch blocks to prevent unhandled exceptions from crashing the application or causing unexpected behavior. This includes property access on unknown objects, API calls, and resource initialization.

Many operations that appear safe can actually throw exceptions. Property access like val.stack can throw, method calls like getReader() can throw, and even seemingly simple operations may have hidden failure modes. Failing to catch these exceptions can lead to application crashes or inconsistent state.

Example of defensive error handling:

// Before - risky property access
if (val && isObject && val.stack && typeof val.stack === 'string') {
  out.push(`Stack:\n${val.stack}`);
}

// After - defensive with try/catch
if (val && isObject && val.stack && typeof val.stack === 'string') {
  try {
    out.push(`Stack:\n${val.stack}`);
  } catch {
    // Ignore errors when accessing stack property
  }
}

// Before - risky method call
this.#reader ??= this._stream.getReader();
const data = await this.#reader.read();

// After - wrapped in try/catch
try {
  this.#reader ??= this._stream.getReader();
  const data = await this.#reader.read();
  // ... handle success
} catch (error) {
  this.destroy(error);
}

When catching exceptions, decide whether to ignore them silently, log them, or propagate them up the call stack based on the context and severity of the failure.

3
Comments Analyzed
TypeScript
Primary Language
Error Handling
Category

Source Discussions