Error Handling And Abort Signals

What happens when the internet fails? We use .catch and the modern AbortSignal to take absolute control of our background work.

April 25, 20262 min read5 / 5

In the previous parts, we've focused on the "happy path"--what happens when our background work completes successfully. But the internet is unpredictable. To write professional code, we must master the "dark path": Error Handling.

The Essentials

  1. Reject Reactions: A second hidden array on the Promise object for functions that run on failure.
  2. .catch(): The method used to add error-handling functions to the onRejected list.
  3. AbortController / AbortSignal: A mechanism to cancel background work (like a network request) if it takes too long.
  4. AbortSignal.timeout(): A modern helper (added in 2022) that automatically aborts a task after a set duration.

The Fail-Safe: .catch()

When we use fetch, a failure (like a lost connection) doesn't just leave our Promise object in limbo. It triggers the Rejection logic.

Every Promise object actually has two hidden arrays:

  • onFulfilled: Triggered when the data arrives.
  • onRejected: Triggered when an error occurs.

We use .catch(handleError) to push functions into the rejection list.

JavaScript
const futureData = fetch('https://tiktok.com/will'); futureData .then(display) .catch(handleError);

If the TikTok server is down, the browser will update the Promise object's hidden state to "rejected" and automatically move handleError into the Microtask Queue.

Taking Manual Control: Abort Signals

Sometimes, we don't want to wait forever for a server. We might want to say, "If this takes more than 200ms, just cancel it."

In 2022, JavaScript added a powerful tool for this: AbortSignal.timeout().

JavaScript
// 1. Create a signal that expires in 200ms const signal = AbortSignal.timeout(200); // 2. Pass the signal to fetch const futureData = fetch('https://tiktok.com/will', { signal }); futureData.catch(err => { if (err.name === 'TimeoutError') { console.log("Too slow! Aborted."); } });

The Invisible Bond

This works by creating a connection between two browser features:

  1. A Timer: Counting down 200ms.
  2. A Network Request: Speaking to TikTok.

If the Timer completes before the Network Request, the browser automatically sends an "Abort" command to the network feature. The network request is killed, the Promise is rejected with a TimeoutError, and our .catch logic runs immediately.

This gives us the ability to prevent "zombie" requests from hanging around and wasting resources.

Summary: From Quirks to First Principles

We've traveled from the foundational single thread of execution to the sophisticated world of priority queues and abort signals.

Asynchronous JavaScript is no longer "magic." It is a system of delegation where:

  • JavaScript handles the logic (Thread, Stack, Memory).
  • The Browser handles the waiting (Web APIs).
  • The Event Loop handles the timing (Microtask & Callback Queues).

By understanding these first-principles, you can build fast, non-blocking applications and navigate the "Hard Parts" of the web with confidence.

In the next chapter, we'll move from how code runs to how we structure it: Classes and Prototypes (OOP).

Further Reading and Watching