TryBugHunt

The Poisoned Promise

Hardjavascript

In-Flight Request Coalescing with Uncaught Rejection Caching

0:00
Step 1: Test Traffic & Expose Flaw
/**
 * Single-Flight Request Deduplicator
 * Coalesces concurrent in-flight requests to the same resource.
 */

class SingleFlightFetcher {
  constructor(backendService) {
    this.backendService = backendService;
    this.inFlight = new Map();
  }

  async fetchProduct(productId) {
    // Coalesce duplicate in-flight requests
    if (this.inFlight.has(productId)) {
      return this.inFlight.get(productId);
    }

    const requestPromise = this.backendService.queryBackend(productId);
    this.inFlight.set(productId, requestPromise);

    try {
      const result = await requestPromise;
      this.inFlight.delete(productId);
      return result;
    } catch (err) {
      // AI Attempt: Re-throws the error to caller
      // ❌ BUG: AI forgot to evict productId from this.inFlight on error!
      throw err;
    }
  }

  getInFlightCount() {
    return this.inFlight.size;
  }
}

module.exports = { SingleFlightFetcher };
Step 1: Test Traffic & Expose FlawClient-side WASM

Run a scenario below to trace catalog lookups. Prove that a single transient 503 error permanently breaks subsequent healthy queries.

Choose Traffic Scenario to TestClick to simulate
Architectural Guide & Interview Notes

Deep Dive: The Poisoned Promise

An engineering analysis of why this AI-generated Pull Request passed isolated unit tests, how multi-tenant traffic exposes the architectural flaw, and how interviewers score your response.

The Root Cause Anti-Pattern

In asynchronous JavaScript, a rejected Promise remains permanently in the rejected state. Caching an in-flight promise to prevent cache stampedes without guaranteed eviction in a finally block leaves rejected promises in cache forever, creating an infinite outage even after downstream recovery.

The Interviewer's Scoring Rubric

Candidates are assessed on whether they jump to trial-and-error editing or follow a hypothesis-driven approach. A "Strong Hire" candidate restates the data flow between modules, explains why single-client unit tests passed, crafts an adversarial probe showing cross-tenant leakage, and implements a surgical 1-line patch without breaking existing contracts.

Candidate Strategy for the Code Comprehension Round

  1. 1Map Module ContractsTrace how the gateway invokes the underlying service. Note what data is passed by reference vs. by value.
  2. 2Break It With An Adversarial ProbeSimulate concurrent or sequential traffic across multiple identities to force shared state mutation.
  3. 3Deliver a Surgical PatchMake the minimal required diff to ensure proper per-client state isolation without refactoring unnecessary files.