Repository: remix-run/react-router
File: packages/router/utils.ts (TypeScript)

Code before:
      this.unlistenAbortSignal();
      Object.defineProperty(promise, "_error", { get: () => error });
      return Promise.reject(error);
    }

    this.pendingKeysSet.delete(key);

    if (this.done) {
      // Nothing left to abort!
      this.unlistenAbortSignal();
    }

    // use argument length to detect error or value resolution
    if (arguments.length === 3) {
      Object.defineProperty(promise, "_error", { get: () => error });
      this.emit(false, key);
      return Promise.reject(error);
    }

    // If the promise was resolved with undefined, we'll throw an error as you
    // should always resolve with a value or null
    if (data === undefined) {
      Object.defineProperty(promise, "_error", {
        get: () =>
          new Error(
            `Deferred data for key ${key} resolved to \`undefined\`, you must resolve with a value or \`null\`.`
          ),
      });
      this.emit(false, key);
      return Promise.reject(error);
    }

    Object.defineProperty(promise, "_data", { get: () => data });
    this.emit(false, key);
    return data;
  }

  private emit(aborted: boolean, settledKey?: string) {
    this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));
  }

  subscribe(fn: (aborted: boolean, settledKey?: string) => void) {
    this.subscribers.add(fn);
    return () => this.subscribers.delete(fn);
  }

  cancel() {
    this.controller.abort();
    this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));
    this.emit(true);
  }

Review comment (bug):
```suggestion
            `Deferred data for key "${key}" resolved to \`undefined\`, you must resolve with a value or \`null\`.`
```

This will break the unit test above and will need to add the quotes in there too

Code after:
      this.unlistenAbortSignal();
      Object.defineProperty(promise, "_error", { get: () => error });
      return Promise.reject(error);
    }

    this.pendingKeysSet.delete(key);

    if (this.done) {
      // Nothing left to abort!
      this.unlistenAbortSignal();
    }

    // If the promise was resolved/rejected with undefined, we'll throw an error as you
    // should always resolve with a value or null
    if (error === undefined && data === undefined) {
      let undefinedError = new Error(
        `Deferred data for key "${key}" resolved/rejected with \`undefined\`, ` +
          `you must resolve/reject with a value or \`null\`.`
      );
      Object.defineProperty(promise, "_error", { get: () => undefinedError });
      this.emit(false, key);
      return Promise.reject(undefinedError);
    }

    if (data === undefined) {
      Object.defineProperty(promise, "_error", { get: () => error });
      this.emit(false, key);
      return Promise.reject(error);
    }

    Object.defineProperty(promise, "_data", { get: () => data });
    this.emit(false, key);
    return data;
  }

  private emit(aborted: boolean, settledKey?: string) {
    this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));
  }

  subscribe(fn: (aborted: boolean, settledKey?: string) => void) {
    this.subscribers.add(fn);
    return () => this.subscribers.delete(fn);
  }

  cancel() {
    this.controller.abort();
    this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));
    this.emit(true);
  }

  async resolveData(signal: AbortSignal) {