Canceling AI Requests

Cancel in-flight AI requests with AbortController when the user navigates away or starts a new query.

TL;DR

  1. Create an AbortController and pass its signal to fetch.
  2. Call controller.abort() to cancel an in-flight request.
  3. Abort the old request whenever a newRequest starts.

Set Up an AbortController

    Create It

    Make a controller for each request you start.

    const controller = new AbortController();
    Pass the Signal

    Hand the signal to fetch so it can cancel.

    fetch(url, { signal: controller.signal });
    Abort It

    Call abort to stop the request at once.

    controller.abort();

Cancel on Unmount

    Cleanup Function

    Return a cleanup that aborts the request.

    useEffect(() => {
      const c = new AbortController();
      run(c.signal);
      return () => c.abort();
    }, []);
    No Stale setState

    Aborting stops updates after unmount.

    // setState never runs post-abort
    Fresh Each Run

    Recreate the controller when deps change.

    // new controller per effect run

Cancel Stale Requests

    Keep a Ref

    Track the current request's controller.

    const ref = useRef<AbortController>();
    Abort the Old

    Cancel the previous before starting anew.

    ref.current?.abort();
    ref.current = new AbortController();
    Latest Wins

    Only the newest send stays running.

    // stale responses are dropped

Handle the Abort

    Catch AbortError

    Aborting rejects the fetch promise.

    catch (e) {
      if (e.name === 'AbortError') return;
      setError(e);
    }
    Ignore Cancels

    A cancel is expected, not a failure.

    // AbortError is normal, skip it
    Stop the Server

    A closed request lets the route stop early.

    req.signal.addEventListener('abort', stop);

Tips

  1. Store the current controller in a ref and abort it before starting the next request, so only the latest answer reaches state.
  2. Abort in a useEffect cleanup so leaving the page stops the request and never sets state on an unmounted component.

Warnings

  1. An aborted fetch throws an AbortError; catch and ignore it, or a normal cancellation will look like a real failure.
  2. Without cancellation, a slow earlier response can overwrite a newer one; this raceCondition shows stale AI answers.

In Practice

FAQ