Skip to content

The waiter configuration should accept abortSignal and not AbortController #2316

Closed
@trivikr

Description

@trivikr

Describe the bug

The waiter configuration accepts abortController

/**
* Abort controller. Used for ending the waiter early.
*/
abortController?: AbortController;

This is not following AbortController spec which recommends APIs to accept AbortSignal object.

The API which wishes to support aborting can accept an AbortSignal object, and use its state to determine how to proceed.

Your environment

SDK version number

@aws-sdk/[email protected]
@aws-sdk/[email protected]

Is the issue in the browser/Node.js/ReactNative?

All

Details of the browser/Node.js/ReactNative version

Tested in Node.js v14.16.1

Steps to reproduce

Code which passes AbortController to waiter

const {
  S3Client,
  CreateBucketCommand,
  waitUntilBucketExists,
} = require("../waiters/aws-sdk-js-v3/clients/client-s3");

(async () => {
  const region = "us-west-2";
  const client = new S3Client({ region });

  const Bucket = "test-bucket-for-abort-controller";
  await client.send(new CreateBucketCommand({ Bucket }));
  const abortController = new AbortController();
  const waiterPromise = waitUntilBucketExists(
    { client, maxWaitTime: 60, abortController },
    { Bucket }
  );

  abortController.abort();
  try {
    await waiterPromise;
  } catch (error) {
    console.log(error);
  }
})();

Note: Code is written on waitUntilOperationName which is introduced in #2302

Observed behavior

The error is thrown as expected:

$ Error: ABORTED
    at waitUntilBucketExists (/local/home/trivikr/workspace/waiters/aws-sdk-js-v3/clients/client-s3/dist/cjs/waiters/waitForBucketExists.js:41:28)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async /local/home/trivikr/workspace/test-waiters/abortController.js:24:5

However, the entire AbortController is sent to API when only AbortSignal needs to be sent.
The spec requires API to only expect AbortSignal. If API accepts AbortController, it can call .abort() internally.

Also, as per the spec an "AbortError" should be thrown.
The waitForUntilOperationName should throw "AbortError" if state is ABORTED

if (abortController?.signal?.aborted) {
return { state: WaiterState.ABORTED };
}

Expected behavior

Accept abortSignal like it's done in client.send() operation, and deprecate abortController configuration.

The example code would be:

const {
  S3Client,
  CreateBucketCommand,
  waitUntilBucketExists,
} = require("../waiters/aws-sdk-js-v3/clients/client-s3");

(async () => {
  const region = "us-west-2";
  const client = new S3Client({ region });

  const Bucket = "test-bucket-for-abort-controller";
  await client.send(new CreateBucketCommand({ Bucket }));
  const abortController = new AbortController();
  const waiterPromise = waitUntilBucketExists(
    { client, maxWaitTime: 60, abortSignal: abortController.signal },
    { Bucket }
  );

  abortController.abort();
  try {
    await waiterPromise;
  } catch (error) {
    console.log(error);
  }
})();

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions