AWS Developer Tools Blog

AbortController in modular AWS SDK for JavaScript

As of December 15th, 2020, the AWS SDK for JavaScript, version 3 (v3) is generally available.

On October 19th, 2020, we published the Release Candidate (RC) of the AWS SDK for JavaScript, version 3 (v3). In v3, we support AbortController interface which allows you to abort requests as and when desired. This blog post will cover the AbortController and how to use it with modular AWS SDK for JavaScript.

Motivation

The Web Hypertext Application Technology Working Group (WHATWG) community started discussions on “Aborting a fetch” several years ago. The goal was to provide developers with a method to abort an action initiated with fetch() in a way that is not overly complicated. After the AbortController specification was finalized in 2017, Edge 16 became the first browser to add support for it, followed by Firefox 57, Chrome 66, Safari 12.1 and others. In October of 2020, the v15.0.0 release of Node.js core added an experimental implementation of AbortController.

Interface

The AbortController Interface provides an abort() method that toggles the state of a corresponding AbortSignal object. The API that wants to support aborting can accept an AbortSignal object, and is encouraged to respond to abort() by rejecting any unsettled promise with an “AbortError”.

// Returns a new controller whose signal is set to a newly created AbortSignal object.
const controller = new AbortController();

// Returns the AbortSignal object associated with controller.
const signal = controller.signal;

// Invoking this method will set controller’s AbortSignal's aborted flag
// and signal to any observers that the associated activity is to be aborted.
controller.abort();

Usage

In JavaScript SDK v3, we added an implementation of WHATWG AbortController interface in @aws-sdk/abort-controller. To use it, you need to send AbortController.signal as abortSignal in the httpOptions parameter when calling .send() operation on the client as follows:

const { AbortController } = require("@aws-sdk/abort-controller");
const { S3Client, CreateBucketCommand } = require("@aws-sdk/client-s3");

...

const abortController = new AbortController();
const client = new S3Client(clientParams);

const requestPromise = client.send(new CreateBucketCommand(commandParams), {
  abortSignal: abortController.signal,
});

// The abortController can be aborted any time.
// The request will not be created if abortSignal is already aborted.
// The request will be destroyed if abortSignal is aborted before response is returned.
abortController.abort();

// This will fail with "AbortError" as abortSignal is aborted.
await requestPromise;

Alternatively, you can substitute AbortController in @aws-sdk/abort-controller with any other WHATWG AbortController interface, like AbortController Web API or abort-controller npm package or Node.js AbortController implementation.

Example

The following code snippet shows how to upload a file using S3 putObject API in the browser with support to abort the upload. First, create a controller using the AbortController() constructor, then grab a reference to its associated AbortSignal object using the AbortController.signal property. When the PutObjectCommand is called with .send() operation, pass in AbortController.signal as abortSignal in the httpOptions parameter. This will allow you to abort the PutObject operation by calling abortController.abort().

const abortController = new AbortController();
const abortSignal = abortController.signal;

const uploadBtn = document.querySelector('.upload');
const abortBtn = document.querySelector('.abort');

uploadBtn.addEventListener('click', uploadObject);

abortBtn.addEventListener('click', function() {
  abortController.abort();
  console.log('Upload aborted');
});

const uploadObject = async (file) => {
  ...
  const client = new S3Client(clientParams);
  try {
    await client.send(new PutObjectCommand(commandParams), { abortSignal });
  } catch(e) {
    if (e.name === "AbortError") {
      uploadProgress.textContent = 'Upload aborted: ' + e.message;
    }
    ...
  }
}

Feedback

We value your feedback, so please tell us what you like and don’t like by opening an issue on GitHub.

Trivikram Kamat

Trivikram Kamat

Trivikram is maintainer of AWS SDK for JavaScript in Node.js and browser. Trivikram is also a Node.js Core collaborator and have contributed to HTTP, HTTP/2 and HTTP/3 over QUIC implementations in the past. He has been writing JavaScript for over a decade. You can find him on Twitter @trivikram and GitHub @trivikr.