aws / aws-sdk-js-v3

Modularized AWS SDK for JavaScript.
Apache License 2.0
3.01k stars 565 forks source link

Node 20 seems incompatible with streaming client (still) #5633

Open qhenkart opened 7 months ago

qhenkart commented 7 months ago

Checkboxes for prior research

Describe the bug

This issue still exists https://github.com/aws/aws-sdk-js-v3/issues/5265

in case you don't click on the link above, here is the issue

TypeError: Failed to construct 'Request': Request with GET/HEAD method cannot have body.
    at FetchHttpHandler.handle (vendors-_yarn___virtual___react-beautiful-dnd-virtual-e0869911dd_0_cache_react-beautiful-dnd--c9fc4a.bundle.js:18650:30)
 import { StartStreamTranscriptionCommand, TranscribeStreamingClient } from "@aws-sdk/client-transcribe-streaming"
        | ^
import { PassThrough } from "readable-stream"
import mic from "microphone-stream"

      at Runtime.createScriptFromCode (.yarn/cache/jest-runtime-npm-29.7.0-120fa64128-d19f113d01.zip/node_modules/jest-runtime/build/index.js:1505:14)
      at Object.<anonymous> (.yarn/cache/@aws-sdk-middleware-sdk-transcribe-streaming-npm-3.418.0-1473b98fc2-dc71c380d9.zip/node_modules/@aws-sdk/middleware-sdk-transcribe-streaming/dist-cjs/middleware-inject-response-values.js:4:16)
      at Object.<anonymous> (.yarn/cache/@aws-sdk-middleware-sdk-transcribe-streaming-npm-3.418.0-1473b98fc2-dc71c380d9.zip/node_modules/@aws-sdk/middleware-sdk-transcribe-streaming/dist-cjs/getTranscribeStreamingPlugin.js:4:45)
      at Object.<anonymous> (.yarn/cache/@aws-sdk-middleware-sdk-transcribe-streaming-npm-3.418.0-1473b98fc2-dc71c380d9.zip/node_modules/@aws-sdk/middleware-sdk-transcribe-streaming/dist-cjs/index.js:5:22)
      at Object.<anonymous> (.yarn/cache/@aws-sdk-client-transcribe-streaming-npm-3.418.0-88537ebf7b-7b03a07c71.zip/node_modules/@aws-sdk/client-transcribe-streaming/dist-cjs/TranscribeStreamingClient.js:8:47)
      at Object.<anonymous> (.yarn/cache/@aws-sdk-client-transcribe-streaming-npm-3.418.0-88537ebf7b-7b03a07c71.zip/node_modules/@aws-sdk/client-transcribe-streaming/dist-cjs/index.js:5:22)
      at Object.require (src/action_creators/audio_recording/liveTranscription.js:1:1)
      at Object.require (src/components/transcriptions/containers/AudioRecorder.js:11:1)
      at Object.require (src/components/cards/containers/CardDisplay.jsx:26:1)
      at Object.require (src/components/cards/containers/CardTransition.js:3:1)
      at Object.require (src/components/cards/__tests__/CardTransition.test.js:4:1)

Below are triage steps I attempted to make based on suggestions in the original closed ticket

  1. I upgraded to Node v20.10.0 and upgraded aws-sdk-js-v3 to the latest and rebuilt my yarn.lock file
  2. Following this advice https://github.com/aws/aws-sdk-js-v3/issues/5265#issuecomment-1742876331 I tried to downgrade to a previous version (it did not work)
  3. following this advice https://github.com/aws/aws-sdk-js-v3/issues/5265#issuecomment-1743408653 I manually installed the latest version of @smithy/fetch-http-handler (it did not work)
  4. following this advice https://github.com/aws/aws-sdk-js-v3/issues/5265#issuecomment-1743498985 I deleted my lock file and did a fresh install (it did not work)
  5. because of this issue https://github.com/aws/aws-sdk-js-v3/issues/5632, I had to install @smithy/eventstream-codec manually

I downgraded to a number of versions to try to find one that works. After a few tries, I installed "@aws-sdk/client-transcribe-streaming": "v3.236.0", I was forced to manually install @aws-sdk/util-utf8-browser" because of another illegal dependency call

I'm probably just going to update our code to create our own streaming solution at this point, but I wanted to report the issue anyway

SDK version number

@aws-sdk/client-transcribe-streaming@3.484.0

Which JavaScript Runtime is this issue in?

Browser

Details of the browser/Node.js/ReactNative version

v20.10.0, Chrome (latest)

Reproduction Steps

The code comes directly from AWS' documentation

import { StartStreamTranscriptionCommand, TranscribeStreamingClient } from "@aws-sdk/client-transcribe-streaming"
import { PassThrough } from "stream"
import mic from "microphone-stream"

const streamAudioToWebSocket = async (dispatch, micStream) => {
  const audioPayloadStream = new PassThrough({ highWaterMark: 1 * 1024 }) // Stream chunk less than 1 KB

  const transcribeInput = async function* () {
    micStream.pipe(audioPayloadStream)

    for await (const chunk of audioPayloadStream) {
      let encoded = pcmEncodeChunk(chunk)
      yield { AudioEvent: { AudioChunk: encoded } }
    }
  }

  client = new TranscribeStreamingClient({
    region: "us-west-2",
    signer: () => {
      return {
        presign: () => {
          return Promise.resolve({ protocol: "wss", hostname: "", path: `${internalAPIEndpoint_redacted}` })
        },
      }
    },
  })

  try {
    const res = await client.send(
      new StartStreamTranscriptionCommand({
        AudioStream: transcribeInput(),
      })
    )

    await handleResult(dispatch, res)
  } catch (e) {
    console.log(e)
  } finally {
    closeSocket()
  }
}

Observed Behavior

No network requests are made due to the following exception:

TypeError: Failed to construct 'Request': Request with GET/HEAD method cannot have body. at FetchHttpHandler.handle

Expected Behavior

successful websocket connection

Possible Solution

compatibility with Yarn (latest) pnp

Additional Information/Context

yarn v4.0.2 .yarnrc.yml

compressionLevel: mixed

enableGlobalCache: false

enableScripts: false

nodeLinker: pnp

yarnPath: .yarn/releases/yarn-4.0.2.cjs
RanVaknin commented 7 months ago

Hi @qhenkart ,

I reproduced #5632, but Im not sure why you opened this issue. The solution here should not be to downgrade the version to get it to work in an older dependency. We will look into resolving #5632.

Since the problem you are describing in this thread is with an older version, Im going to close it.

Thanks, Ran~

qhenkart commented 7 months ago

@RanVaknin There seems to be some confusion. This issue is not about failed dependencies, this issue is about failed functionality. Please refer to the original issue that was closed due to inactivity https://github.com/aws/aws-sdk-js-v3/issues/5265

To be clear, the streaming client is currently broken on its latest version on node-v20, I apologize for any confusion in my issue that led you to think otherwise

The issue is simply that the transcribe client does not work because it tries to put a request body into the initiating websocket GET request

TypeError: Failed to construct 'Request': Request with GET/HEAD method cannot have body.
    at FetchHttpHandler.handle (vendors-_yarn___virtual___react-beautiful-dnd-virtual-e0869911dd_0_cache_react-beautiful-dnd--c9fc4a.bundle.js:18650:30)

I attempted to downgrade based on your advice here https://github.com/aws/aws-sdk-js-v3/issues/5265#issuecomment-1742876331, to try to help you isolate the whether the update to smithy was indeed introducing a breaking change or not (it did not based on my investigation)

It should be noted that the transcribe client code comes directly from examples provided by aws

qhenkart commented 7 months ago

I have updated the original post to contain more of the context from the original that was closed due to inactivity but still is occurring which should remove the confusion about it relating to a broken dependency call

RanVaknin commented 7 months ago

Hi @qhenkart,

Thanks for the clarification. We have created a PR to close #5265 .

Regarding this statement:

To be clear, the streaming client is currently broken on its latest version on node-v20, I apologize for any confusion in my issue that led you to think otherwise

I'm able to run an example code using the streaming client using node 20 and a .flac audio file I recorded. Here is my reproduction:

import { TranscribeStreamingClient, StartStreamTranscriptionCommand } from "@aws-sdk/client-transcribe-streaming";
import { PassThrough } from "stream";
import { createReadStream } from "fs";

const audioSource = createReadStream("./sample_recording.flac");
const audioPayloadStream = new PassThrough({ highWaterMark: 512 });
audioSource.pipe(audioPayloadStream);

const audioStream = async function* () {
  for await (const payloadChunk of audioPayloadStream) {
    yield { AudioEvent: { AudioChunk: payloadChunk } };
  }
};

const client = new TranscribeStreamingClient({ region: 'us-east-1' });

async function main() {
  try {
    const response = await client.send(new StartStreamTranscriptionCommand({
      LanguageCode: "en-US",
      MediaEncoding: "flac",
      MediaSampleRateHertz: 44100,
      AudioStream: audioStream(),
    }));

    for await (const event of response.TranscriptResultStream) {
      if (event.TranscriptEvent && event.TranscriptEvent.Transcript.Results.length > 0) {
        const results = event.TranscriptEvent.Transcript.Results;
        for (const result of results) {
          if (result.IsPartial === false) {
            const transcript = result.Alternatives[0].Transcript;
            console.log(transcript);
          }
        }
      }
    }
  } catch (error) {
    console.error("Error:", error);
  }
}

main();

Here is the successful output:

$ node sample.mjs
Hi, everyone. Welcome to this audio demonstration made by me your host Ron Vaknin.
$ node -v
v20.10.0
$ npm ls @aws-sdk/client-transcribe-streaming
/Users/rvaknin/test_folder/3720_transcribeClient_connections_destroy
└── @aws-sdk/client-transcribe-streaming@3.485.

Am I missing anything?

Thank you very much, Ran~

kuhe commented 7 months ago

The reported issue is in a browser so it's probably not enough to write a Node.js sample.

github-actions[bot] commented 7 months ago

This issue has not received a response in 1 week. If you still think there is a problem, please leave a comment to avoid the issue from automatically closing.

qhenkart commented 7 months ago

@RanVaknin The issue occurs in the browser this error

TypeError: Failed to construct 'Request': Request with GET/HEAD method cannot have body. at FetchHttpHandler.handle (vendors-_yarnvirtualreact-beautiful-dnd-virtual-e0869911dd_0_cache_react-beautiful-dnd--c9fc4a.bundle.js:18650:30)

Comes directly from the Chrome console