Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S3 Body.toString() not returning the object's content #1096

Closed
imedadel opened this issue Apr 15, 2020 · 9 comments
Closed

S3 Body.toString() not returning the object's content #1096

imedadel opened this issue Apr 15, 2020 · 9 comments
Labels
closing-soon This issue will automatically close in 4 days unless further comments are made. guidance General information and guidance, answers to FAQs, or recommended best practices/resources.

Comments

@imedadel
Copy link

Describe the bug
Running GetObject and then Body.toString() is suddenly not returning a string anymore. Instead, I am getting an IncomingMessage object (stringified). I am using TypeScript 3.8.3.

SDK version number
1.0.0-beta.3

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

Details of the browser/Node.js version
Tested on v12.6.1 and v13.12

To Reproduce (observed behavior)
Steps to reproduce the behavior (please share code or minimal repo)

import {
	S3Client,
	GetObjectCommand,
} from "@aws-sdk/client-s3"

async function getContent({ uid }) {
	try {
		console.log("> Getting content from S3")
		const s3Client = new S3Client({
			region: "us-east-1",
		})
		const command = new GetObjectCommand({
			Key: `content/${uid}.txt`,
			Bucket: "archive",
		})
		const s3Item = await s3Client.send(command)
		console.log("> Content received.")

		return s3Item.Body.toString()
	} catch {
		console.log(`> Error.`)
	}
}

Expected behavior
A string containing the content stored in under the object's key in S3.

@makeitraina
Copy link

+1 reproduced on NodeJs v12.6.1 with version 1.0.0-beta.3

@abierbaum
Copy link

Reproduced here too. I can't find a way to download an S3 object with the SDK. Does anyone have a full example of how to make this work with the latest APIs?

@imedadel
Copy link
Author

I went back to using v2 :(

@abierbaum
Copy link

I think I figured it out. The new APIs are returning Node streams. So you need to read the streams using the stream interfaces. In my case I am just going to use the get-stream npm package to read into a Buffer.

@imedadel
Copy link
Author

Please tell us if the this solution worked for you :)

@abierbaum
Copy link

abierbaum commented Apr 20, 2020

@imedadel Yes, it is working. I haven't cleaned up error handling, but this is working for me right now.

const resp: s3.GetObjectCommandOutput = await this.s3Client.getObject({
   Bucket: this.opts.bucketName,
   Key: objkey,
});

const file_stream = resp.Body!;
let content_buffer: Buffer | null = null;

if (file_stream instanceof Readable) {
   content_buffer = await getStream.buffer(file_stream as any);
} else {
   throw new Error('Unknown object stream type.');
}

@AllanZhengYP
Copy link
Contributor

AllanZhengYP commented Apr 28, 2020

Hi, @abierbaum @imedadel @makeitraina

This is an expected API change from V2 to V3. In v2 the SDK always buffer the downloaded data so you can call toString() on the data easily. But it will bring us problem when the data is very big, and SDK will buffer all of the data in the memory. Now the response Body is a ReadableStream. As @abierbaum has pointed out you can consume the stream like in the sample. You can download the data easily like:

import {
	S3Client,
	GetObjectCommand,
} from "@aws-sdk/client-s3";
import {Readable} from "stream";
import {createWriteStream} from "fs";

async function getContent({ uid }) {
	try {
		console.log("> Getting content from S3");
		const s3Client = new S3Client({
			region: "us-east-1",
		});
		const command = new GetObjectCommand({
			Key: `content/${uid}.txt`,
			Bucket: "archive",
		});
		const s3Item = await s3Client.send(command);
                 s3Item.Body.pipe(createWriteStream(fileName));
	} catch {
		console.log(`> Error.`);
	}
}

@AllanZhengYP AllanZhengYP added guidance General information and guidance, answers to FAQs, or recommended best practices/resources. closing-soon This issue will automatically close in 4 days unless further comments are made. labels Apr 28, 2020
@imedadel
Copy link
Author

Thanks, everyone! Since it's intentional and I suppose will be documented soon. We can close this issue :)

@lock
Copy link

lock bot commented May 6, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@lock lock bot locked as resolved and limited conversation to collaborators May 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
closing-soon This issue will automatically close in 4 days unless further comments are made. guidance General information and guidance, answers to FAQs, or recommended best practices/resources.
Projects
None yet
Development

No branches or pull requests

4 participants