Core object storage operations for uploading, downloading, copying, and managing S3 objects with comprehensive metadata and configuration support.
Upload objects to S3 with support for metadata, storage classes, and server-side encryption.
/**
* Upload an object to S3
*/
class PutObjectCommand {
constructor(input: PutObjectCommandInput);
}
interface PutObjectCommandInput {
/** Target bucket name */
Bucket: string;
/** Object key (path/filename) */
Key: string;
/** Object content (string, Buffer, Stream, etc.) */
Body?: StreamingBlobPayloadInputTypes;
/** Object permissions */
ACL?: ObjectCannedACL;
/** Cache control header */
CacheControl?: string;
/** Content disposition header */
ContentDisposition?: string;
/** Content encoding header */
ContentEncoding?: string;
/** Content language header */
ContentLanguage?: string;
/** Content length in bytes */
ContentLength?: number;
/** MD5 hash of the content */
ContentMD5?: string;
/** MIME type of the content */
ContentType?: string;
/** Object expiration date */
Expires?: Date;
/** User-defined metadata */
Metadata?: Record<string, string>;
/** Server-side encryption algorithm */
ServerSideEncryption?: ServerSideEncryption;
/** KMS key ID for encryption */
SSEKMSKeyId?: string;
/** Storage class for the object */
StorageClass?: StorageClass;
/** Object tagging */
Tagging?: string;
/** Website redirect location */
WebsiteRedirectLocation?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
/** Object lock mode */
ObjectLockMode?: ObjectLockMode;
/** Object lock retain until date */
ObjectLockRetainUntilDate?: Date;
/** Object lock legal hold status */
ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus;
/** Checksum algorithm */
ChecksumAlgorithm?: ChecksumAlgorithm;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
}
interface PutObjectCommandOutput {
/** ETag of the uploaded object */
ETag?: string;
/** Server-side encryption algorithm used */
ServerSideEncryption?: ServerSideEncryption;
/** Version ID of the object (if versioning enabled) */
VersionId?: string;
/** KMS key ID used for encryption */
SSEKMSKeyId?: string;
/** Request charged information */
RequestCharged?: RequestCharged;
/** Checksum values */
ChecksumCRC32?: string;
ChecksumCRC32C?: string;
ChecksumSHA1?: string;
ChecksumSHA256?: string;
}Usage Examples:
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { readFileSync } from "fs";
const client = new S3Client({ region: "us-east-1" });
// Upload text content
const textUpload = new PutObjectCommand({
Bucket: "my-bucket",
Key: "documents/readme.txt",
Body: "Hello, S3!",
ContentType: "text/plain",
Metadata: {
author: "John Doe",
category: "documentation"
}
});
await client.send(textUpload);
// Upload file with encryption
const fileUpload = new PutObjectCommand({
Bucket: "secure-bucket",
Key: "sensitive/data.json",
Body: readFileSync("./data.json"),
ContentType: "application/json",
ServerSideEncryption: "aws:kms",
SSEKMSKeyId: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012",
StorageClass: "STANDARD_IA"
});
await client.send(fileUpload);
// Upload with storage class and tagging
const archiveUpload = new PutObjectCommand({
Bucket: "archive-bucket",
Key: "backups/backup-2024.zip",
Body: readFileSync("./backup.zip"),
StorageClass: "GLACIER",
Tagging: "type=backup&year=2024&retention=7years"
});
await client.send(archiveUpload);Download objects from S3 with support for range requests and conditional downloads.
/**
* Download an object from S3
*/
class GetObjectCommand {
constructor(input: GetObjectCommandInput);
}
interface GetObjectCommandInput {
/** Source bucket name */
Bucket: string;
/** Object key to download */
Key: string;
/** Return only if modified since date */
IfModifiedSince?: Date;
/** Return only if not modified since date */
IfUnmodifiedSince?: Date;
/** Return only if ETag matches */
IfMatch?: string;
/** Return only if ETag doesn't match */
IfNoneMatch?: string;
/** Byte range to download (e.g., "bytes=0-1023") */
Range?: string;
/** Override response cache control */
ResponseCacheControl?: string;
/** Override response content disposition */
ResponseContentDisposition?: string;
/** Override response content encoding */
ResponseContentEncoding?: string;
/** Override response content language */
ResponseContentLanguage?: string;
/** Override response content type */
ResponseContentType?: string;
/** Override response expires header */
ResponseExpires?: Date;
/** Version ID to download (if versioning enabled) */
VersionId?: string;
/** SSE customer algorithm */
SSECustomerAlgorithm?: string;
/** SSE customer key */
SSECustomerKey?: string;
/** SSE customer key MD5 */
SSECustomerKeyMD5?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
/** Part number for multipart object */
PartNumber?: number;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
/** Checksum mode */
ChecksumMode?: ChecksumMode;
}
interface GetObjectCommandOutput {
/** Object content stream */
Body?: StreamingBlobPayloadOutputTypes;
/** Delete marker flag */
DeleteMarker?: boolean;
/** Object expiration info */
Expiration?: string;
/** Restore status for archived objects */
Restore?: string;
/** Last modified date */
LastModified?: Date;
/** Content length in bytes */
ContentLength?: number;
/** ETag of the object */
ETag?: string;
/** Checksum values */
ChecksumCRC32?: string;
ChecksumCRC32C?: string;
ChecksumSHA1?: string;
ChecksumSHA256?: string;
/** Number of parts (for multipart objects) */
PartsCount?: number;
/** Object tags count */
TagCount?: number;
/** Version ID */
VersionId?: string;
/** Cache control header */
CacheControl?: string;
/** Content disposition header */
ContentDisposition?: string;
/** Content encoding header */
ContentEncoding?: string;
/** Content language header */
ContentLanguage?: string;
/** Content type header */
ContentType?: string;
/** Expiration header */
Expires?: Date;
/** User-defined metadata */
Metadata?: Record<string, string>;
/** Storage class */
StorageClass?: StorageClass;
/** Server-side encryption info */
ServerSideEncryption?: ServerSideEncryption;
SSEKMSKeyId?: string;
}Usage Examples:
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { writeFileSync } from "fs";
const client = new S3Client({ region: "us-east-1" });
// Download complete object
const download = new GetObjectCommand({
Bucket: "my-bucket",
Key: "documents/readme.txt"
});
const response = await client.send(download);
const content = await response.Body?.transformToString();
console.log(content);
// Download with range request (first 1KB)
const partialDownload = new GetObjectCommand({
Bucket: "my-bucket",
Key: "large-file.zip",
Range: "bytes=0-1023"
});
const partialResponse = await client.send(partialDownload);
// Download specific version
const versionDownload = new GetObjectCommand({
Bucket: "versioned-bucket",
Key: "document.pdf",
VersionId: "3/L4kqtJlcpXroDTDmpUMLUo"
});
const versionResponse = await client.send(versionDownload);
// Conditional download (only if modified)
const conditionalDownload = new GetObjectCommand({
Bucket: "my-bucket",
Key: "data.json",
IfModifiedSince: new Date("2024-01-01")
});
const conditionalResponse = await client.send(conditionalDownload);Copy objects within S3 or between buckets with metadata preservation or modification.
/**
* Copy an object within S3
*/
class CopyObjectCommand {
constructor(input: CopyObjectCommandInput);
}
interface CopyObjectCommandInput {
/** Destination bucket name */
Bucket: string;
/** Source object specification (bucket/key) */
CopySource: string;
/** Destination object key */
Key: string;
/** Destination object permissions */
ACL?: ObjectCannedACL;
/** Cache control for destination */
CacheControl?: string;
/** Content disposition for destination */
ContentDisposition?: string;
/** Content encoding for destination */
ContentEncoding?: string;
/** Content language for destination */
ContentLanguage?: string;
/** Content type for destination */
ContentType?: string;
/** Copy source if modified since */
CopySourceIfModifiedSince?: Date;
/** Copy source if unmodified since */
CopySourceIfUnmodifiedSince?: Date;
/** Copy source if ETag matches */
CopySourceIfMatch?: string;
/** Copy source if ETag doesn't match */
CopySourceIfNoneMatch?: string;
/** Expiration date for destination */
Expires?: Date;
/** Metadata directive (COPY or REPLACE) */
MetadataDirective?: MetadataDirective;
/** New metadata for destination */
Metadata?: Record<string, string>;
/** Server-side encryption for destination */
ServerSideEncryption?: ServerSideEncryption;
/** Storage class for destination */
StorageClass?: StorageClass;
/** Website redirect location */
WebsiteRedirectLocation?: string;
/** KMS key for destination encryption */
SSEKMSKeyId?: string;
/** Source version ID */
CopySourceVersionId?: string;
/** Object tagging directive */
TaggingDirective?: TaggingDirective;
/** Tags for destination object */
Tagging?: string;
}
interface CopyObjectCommandOutput {
/** Copy result information */
CopyObjectResult?: CopyObjectResult;
/** Expiration info */
Expiration?: string;
/** Version ID of destination */
VersionId?: string;
/** Server-side encryption used */
ServerSideEncryption?: ServerSideEncryption;
/** KMS key ID used */
SSEKMSKeyId?: string;
/** Request charged information */
RequestCharged?: RequestCharged;
}
interface CopyObjectResult {
/** ETag of copied object */
ETag?: string;
/** Last modified date */
LastModified?: Date;
/** Checksum values */
ChecksumCRC32?: string;
ChecksumCRC32C?: string;
ChecksumSHA1?: string;
ChecksumSHA256?: string;
}Usage Examples:
import { S3Client, CopyObjectCommand } from "@aws-sdk/client-s3";
const client = new S3Client({ region: "us-east-1" });
// Simple copy within same bucket
const simpleCopy = new CopyObjectCommand({
Bucket: "my-bucket",
CopySource: "my-bucket/original/file.txt",
Key: "backup/file.txt"
});
await client.send(simpleCopy);
// Copy between buckets with new metadata
const crossBucketCopy = new CopyObjectCommand({
Bucket: "destination-bucket",
CopySource: "source-bucket/data/report.pdf",
Key: "reports/monthly-report.pdf",
MetadataDirective: "REPLACE",
Metadata: {
"copied-date": new Date().toISOString(),
"original-bucket": "source-bucket"
},
StorageClass: "STANDARD_IA"
});
await client.send(crossBucketCopy);
// Conditional copy with encryption
const encryptedCopy = new CopyObjectCommand({
Bucket: "secure-bucket",
CopySource: "temp-bucket/upload.doc",
Key: "documents/secure-doc.doc",
CopySourceIfModifiedSince: new Date("2024-01-01"),
ServerSideEncryption: "aws:kms",
SSEKMSKeyId: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"
});
await client.send(encryptedCopy);Delete single or multiple objects from S3 with support for versioned buckets.
/**
* Delete a single object
*/
class DeleteObjectCommand {
constructor(input: DeleteObjectCommandInput);
}
interface DeleteObjectCommandInput {
/** Target bucket name */
Bucket: string;
/** Object key to delete */
Key: string;
/** Multi-factor authentication token */
MFA?: string;
/** Version ID to delete (for versioned buckets) */
VersionId?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
/** Bypass governance mode retention */
BypassGovernanceRetention?: boolean;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
}
interface DeleteObjectCommandOutput {
/** Delete marker created */
DeleteMarker?: boolean;
/** Version ID deleted */
VersionId?: string;
/** Request charged information */
RequestCharged?: RequestCharged;
}
/**
* Delete multiple objects in a single request
*/
class DeleteObjectsCommand {
constructor(input: DeleteObjectsCommandInput);
}
interface DeleteObjectsCommandInput {
/** Target bucket name */
Bucket: string;
/** Objects to delete specification */
Delete: Delete;
/** Multi-factor authentication token */
MFA?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
/** Bypass governance mode retention */
BypassGovernanceRetention?: boolean;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
/** Checksum algorithm */
ChecksumAlgorithm?: ChecksumAlgorithm;
}
interface Delete {
/** List of objects to delete */
Objects: ObjectIdentifier[];
/** Return detailed results for each object */
Quiet?: boolean;
}
interface ObjectIdentifier {
/** Object key */
Key: string;
/** Version ID (for versioned buckets) */
VersionId?: string;
}
interface DeleteObjectsCommandOutput {
/** Successfully deleted objects */
Deleted?: DeletedObject[];
/** Objects that couldn't be deleted */
Errors?: Error[];
/** Request charged information */
RequestCharged?: RequestCharged;
}Usage Examples:
import { S3Client, DeleteObjectCommand, DeleteObjectsCommand } from "@aws-sdk/client-s3";
const client = new S3Client({ region: "us-east-1" });
// Delete single object
const singleDelete = new DeleteObjectCommand({
Bucket: "my-bucket",
Key: "temp/file-to-delete.txt"
});
await client.send(singleDelete);
// Delete specific version
const versionDelete = new DeleteObjectCommand({
Bucket: "versioned-bucket",
Key: "document.pdf",
VersionId: "3/L4kqtJlcpXroDTDmpUMLUo"
});
await client.send(versionDelete);
// Delete multiple objects
const bulkDelete = new DeleteObjectsCommand({
Bucket: "cleanup-bucket",
Delete: {
Objects: [
{ Key: "temp/file1.txt" },
{ Key: "temp/file2.txt" },
{ Key: "old/archive.zip" }
],
Quiet: false
}
});
const deleteResult = await client.send(bulkDelete);
console.log(`Deleted ${deleteResult.Deleted?.length} objects`);Retrieve object metadata without downloading the content.
/**
* Get object metadata without downloading content
*/
class HeadObjectCommand {
constructor(input: HeadObjectCommandInput);
}
interface HeadObjectCommandInput {
/** Source bucket name */
Bucket: string;
/** Object key */
Key: string;
/** Return only if modified since */
IfModifiedSince?: Date;
/** Return only if unmodified since */
IfUnmodifiedSince?: Date;
/** Return only if ETag matches */
IfMatch?: string;
/** Return only if ETag doesn't match */
IfNoneMatch?: string;
/** Range for partial metadata */
Range?: string;
/** Version ID */
VersionId?: string;
/** SSE customer algorithm */
SSECustomerAlgorithm?: string;
/** SSE customer key */
SSECustomerKey?: string;
/** SSE customer key MD5 */
SSECustomerKeyMD5?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
/** Part number */
PartNumber?: number;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
/** Checksum mode */
ChecksumMode?: ChecksumMode;
}
interface HeadObjectCommandOutput {
/** Delete marker flag */
DeleteMarker?: boolean;
/** Accept ranges header */
AcceptRanges?: string;
/** Expiration info */
Expiration?: string;
/** Restore status */
Restore?: string;
/** Archive status */
ArchiveStatus?: ArchiveStatus;
/** Last modified date */
LastModified?: Date;
/** Content length */
ContentLength?: number;
/** ETag */
ETag?: string;
/** Checksum values */
ChecksumCRC32?: string;
ChecksumCRC32C?: string;
ChecksumSHA1?: string;
ChecksumSHA256?: string;
/** Parts count */
PartsCount?: number;
/** Tag count */
TagCount?: number;
/** Version ID */
VersionId?: string;
/** Content headers */
CacheControl?: string;
ContentDisposition?: string;
ContentEncoding?: string;
ContentLanguage?: string;
ContentType?: string;
Expires?: Date;
/** User metadata */
Metadata?: Record<string, string>;
/** Storage class */
StorageClass?: StorageClass;
/** Encryption info */
ServerSideEncryption?: ServerSideEncryption;
SSEKMSKeyId?: string;
/** Website redirect location */
WebsiteRedirectLocation?: string;
/** Object lock info */
ObjectLockMode?: ObjectLockMode;
ObjectLockRetainUntilDate?: Date;
ObjectLockLegalHoldStatus?: ObjectLockLegalHoldStatus;
}Usage Example:
import { S3Client, HeadObjectCommand } from "@aws-sdk/client-s3";
const client = new S3Client({ region: "us-east-1" });
const headObject = new HeadObjectCommand({
Bucket: "my-bucket",
Key: "documents/report.pdf"
});
const metadata = await client.send(headObject);
console.log(`File size: ${metadata.ContentLength} bytes`);
console.log(`Last modified: ${metadata.LastModified}`);
console.log(`Content type: ${metadata.ContentType}`);
console.log(`User metadata:`, metadata.Metadata);Manage tags on S3 objects for cost allocation, access control, and resource management.
/**
* Get the tag-set of an object
*/
class GetObjectTaggingCommand {
constructor(input: GetObjectTaggingCommandInput);
}
interface GetObjectTaggingCommandInput {
/** Bucket name containing the object */
Bucket: string;
/** Object key */
Key: string;
/** Version ID of the object */
VersionId?: string;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
}
interface GetObjectTaggingCommandOutput {
/** Version ID of the object */
VersionId?: string;
/** Tag set */
TagSet: Tag[];
}
/**
* Set the tag-set for an object
*/
class PutObjectTaggingCommand {
constructor(input: PutObjectTaggingCommandInput);
}
interface PutObjectTaggingCommandInput {
/** Bucket name containing the object */
Bucket: string;
/** Object key */
Key: string;
/** Version ID of the object */
VersionId?: string;
/** MD5 hash of the content */
ContentMD5?: string;
/** Checksum algorithm */
ChecksumAlgorithm?: ChecksumAlgorithm;
/** Tag set */
Tagging: Tagging;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
}
interface PutObjectTaggingCommandOutput {
/** Version ID of the object */
VersionId?: string;
}
/**
* Remove the tag-set from an object
*/
class DeleteObjectTaggingCommand {
constructor(input: DeleteObjectTaggingCommandInput);
}
interface DeleteObjectTaggingCommandInput {
/** Bucket name containing the object */
Bucket: string;
/** Object key */
Key: string;
/** Version ID of the object */
VersionId?: string;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
}
interface DeleteObjectTaggingCommandOutput {
/** Version ID of the object */
VersionId?: string;
}
// Tagging-related types
interface Tag {
/** Tag name */
Key: string;
/** Tag value */
Value: string;
}
interface Tagging {
/** Collection of tags */
TagSet: Tag[];
}Usage Examples:
import {
S3Client,
GetObjectTaggingCommand,
PutObjectTaggingCommand,
DeleteObjectTaggingCommand
} from "@aws-sdk/client-s3";
const client = new S3Client({ region: "us-east-1" });
// Get object tags
async function getObjectTags(bucket: string, key: string) {
const command = new GetObjectTaggingCommand({
Bucket: bucket,
Key: key
});
const response = await client.send(command);
console.log("Object tags:", response.TagSet);
return response.TagSet;
}
// Set object tags
async function setObjectTags(bucket: string, key: string, tags: Record<string, string>) {
const tagSet = Object.entries(tags).map(([Key, Value]) => ({ Key, Value }));
const command = new PutObjectTaggingCommand({
Bucket: bucket,
Key: key,
Tagging: {
TagSet: tagSet
}
});
const response = await client.send(command);
console.log(`Tags set for ${key}:`, tagSet);
return response;
}
// Remove all tags from an object
async function removeObjectTags(bucket: string, key: string) {
const command = new DeleteObjectTaggingCommand({
Bucket: bucket,
Key: key
});
const response = await client.send(command);
console.log(`All tags removed from ${key}`);
return response;
}
// Add/update specific tags while preserving others
async function updateObjectTags(
bucket: string,
key: string,
newTags: Record<string, string>
) {
try {
// Get existing tags
const existingTags = await getObjectTags(bucket, key);
// Convert to map for easier manipulation
const tagMap = new Map<string, string>();
existingTags.forEach(tag => tagMap.set(tag.Key, tag.Value));
// Add/update new tags
Object.entries(newTags).forEach(([key, value]) => {
tagMap.set(key, value);
});
// Convert back to tag array and set
const updatedTags = Object.fromEntries(tagMap);
return await setObjectTags(bucket, key, updatedTags);
} catch (error) {
if (error instanceof Error && error.name === "NoSuchTagSet") {
// No existing tags, just set the new ones
return await setObjectTags(bucket, key, newTags);
}
throw error;
}
}
// Remove specific tags while preserving others
async function removeSpecificTags(
bucket: string,
key: string,
tagsToRemove: string[]
) {
try {
// Get existing tags
const existingTags = await getObjectTags(bucket, key);
// Filter out tags to remove
const remainingTags = existingTags.filter(
tag => !tagsToRemove.includes(tag.Key)
);
if (remainingTags.length === 0) {
// Remove all tags
return await removeObjectTags(bucket, key);
} else {
// Set the remaining tags
const tagMap = Object.fromEntries(
remainingTags.map(tag => [tag.Key, tag.Value])
);
return await setObjectTags(bucket, key, tagMap);
}
} catch (error) {
if (error instanceof Error && error.name === "NoSuchTagSet") {
console.log("Object has no tags to remove");
return;
}
throw error;
}
}
// Example usage
async function tagManagementExample() {
const bucket = "my-bucket";
const key = "documents/report.pdf";
// Set initial tags
await setObjectTags(bucket, key, {
"Environment": "production",
"Department": "Finance",
"CostCenter": "12345"
});
// Add additional tags
await updateObjectTags(bucket, key, {
"Project": "Q4-Report",
"Owner": "alice@company.com"
});
// Remove specific tags
await removeSpecificTags(bucket, key, ["CostCenter"]);
// Get final tag set
const finalTags = await getObjectTags(bucket, key);
console.log("Final tags:", finalTags);
}Retrieve detailed object metadata and attributes without downloading the content.
/**
* Get detailed object attributes and metadata
*/
class GetObjectAttributesCommand {
constructor(input: GetObjectAttributesCommandInput);
}
interface GetObjectAttributesCommandInput {
/** Bucket name containing the object */
Bucket: string;
/** Object key */
Key: string;
/** Version ID of the object */
VersionId?: string;
/** Maximum number of parts to return */
MaxParts?: number;
/** Part number marker for pagination */
PartNumberMarker?: string;
/** SSE customer algorithm */
SSECustomerAlgorithm?: string;
/** SSE customer key */
SSECustomerKey?: string;
/** SSE customer key MD5 */
SSECustomerKeyMD5?: string;
/** Request payer setting */
RequestPayer?: RequestPayer;
/** Expected bucket owner */
ExpectedBucketOwner?: string;
/** Object attributes to retrieve */
ObjectAttributes: ObjectAttributes[];
}
interface GetObjectAttributesCommandOutput {
/** Delete marker flag */
DeleteMarker?: boolean;
/** Last modified date */
LastModified?: Date;
/** Version ID */
VersionId?: string;
/** Request charged */
RequestCharged?: RequestCharged;
/** ETag */
ETag?: string;
/** Checksum details */
Checksum?: Checksum;
/** Object parts information */
ObjectParts?: GetObjectAttributesParts;
/** Storage class */
StorageClass?: StorageClass;
/** Object size */
ObjectSize?: number;
}
type ObjectAttributes =
| "ETag"
| "Checksum"
| "ObjectParts"
| "StorageClass"
| "ObjectSize";
interface GetObjectAttributesParts {
/** Whether more parts exist */
IsTruncated?: boolean;
/** Maximum parts returned */
MaxParts?: number;
/** Next part number marker */
NextPartNumberMarker?: string;
/** Part number marker */
PartNumberMarker?: string;
/** Array of object parts */
Parts?: ObjectPart[];
/** Total parts count */
PartsCount?: number;
}
interface ObjectPart {
/** Part number */
PartNumber?: number;
/** Part size */
Size?: number;
/** Checksum CRC32 */
ChecksumCRC32?: string;
/** Checksum CRC32C */
ChecksumCRC32C?: string;
/** Checksum SHA1 */
ChecksumSHA1?: string;
/** Checksum SHA256 */
ChecksumSHA256?: string;
}
interface Checksum {
/** Checksum CRC32 */
ChecksumCRC32?: string;
/** Checksum CRC32C */
ChecksumCRC32C?: string;
/** Checksum SHA1 */
ChecksumSHA1?: string;
/** Checksum SHA256 */
ChecksumSHA256?: string;
}Usage Example:
import { S3Client, GetObjectAttributesCommand } from "@aws-sdk/client-s3";
const client = new S3Client({ region: "us-east-1" });
async function getObjectDetails(bucket: string, key: string) {
const command = new GetObjectAttributesCommand({
Bucket: bucket,
Key: key,
ObjectAttributes: ["ETag", "ObjectSize", "StorageClass", "Checksum"]
});
const response = await client.send(command);
console.log(`Object: ${key}`);
console.log(`Size: ${response.ObjectSize} bytes`);
console.log(`ETag: ${response.ETag}`);
console.log(`Storage Class: ${response.StorageClass}`);
console.log(`Last Modified: ${response.LastModified}`);
if (response.Checksum) {
console.log("Checksums:", response.Checksum);
}
return response;
}
// Get multipart object details
async function getMultipartObjectParts(bucket: string, key: string) {
const command = new GetObjectAttributesCommand({
Bucket: bucket,
Key: key,
ObjectAttributes: ["ObjectParts"],
MaxParts: 1000
});
const response = await client.send(command);
if (response.ObjectParts) {
console.log(`Total parts: ${response.ObjectParts.PartsCount}`);
console.log(`Parts returned: ${response.ObjectParts.Parts?.length}`);
response.ObjectParts.Parts?.forEach((part, index) => {
console.log(`Part ${part.PartNumber}: ${part.Size} bytes`);
});
}
return response;
}Comprehensive error handling patterns for S3 operations with specific exception types and retry strategies.
// Base S3 exception class
class S3ServiceException extends Error {
name: string;
$fault: "client" | "server";
$metadata: ResponseMetadata;
$retryable?: RetryableTrait;
}
// Common S3 error types
interface ResponseMetadata {
httpStatusCode?: number;
requestId?: string;
extendedRequestId?: string;
cfId?: string;
attempts?: number;
}
// Common error names
type S3ErrorName =
| "NoSuchBucket"
| "NoSuchKey"
| "BucketAlreadyExists"
| "BucketNotEmpty"
| "AccessDenied"
| "InvalidBucketName"
| "InvalidRequest"
| "ServiceUnavailable"
| "SlowDown"
| "RequestTimeout";Error Handling Examples:
import {
S3Client,
PutObjectCommand,
GetObjectCommand,
S3ServiceException
} from "@aws-sdk/client-s3";
const client = new S3Client({ region: "us-east-1" });
// Basic error handling
async function uploadWithErrorHandling(bucket: string, key: string, content: string) {
try {
const command = new PutObjectCommand({
Bucket: bucket,
Key: key,
Body: content
});
const result = await client.send(command);
console.log(`Upload successful: ${result.ETag}`);
return result;
} catch (error) {
if (error instanceof S3ServiceException) {
console.error(`S3 Error: ${error.name}`);
console.error(`Status: ${error.$metadata.httpStatusCode}`);
console.error(`Request ID: ${error.$metadata.requestId}`);
// Handle specific error types
switch (error.name) {
case "NoSuchBucket":
console.error("Bucket does not exist");
break;
case "AccessDenied":
console.error("Insufficient permissions");
break;
case "InvalidBucketName":
console.error("Bucket name is invalid");
break;
case "ServiceUnavailable":
console.error("S3 service temporarily unavailable");
break;
default:
console.error(`Unhandled S3 error: ${error.message}`);
}
} else {
console.error("Non-S3 error:", error);
}
throw error;
}
}
// Advanced error handling with retry logic
async function downloadWithRetry(
bucket: string,
key: string,
maxRetries: number = 3
): Promise<string> {
let lastError: Error;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const command = new GetObjectCommand({
Bucket: bucket,
Key: key
});
const response = await client.send(command);
const content = await response.Body?.transformToString();
if (!content) {
throw new Error("Empty response body");
}
return content;
} catch (error) {
lastError = error as Error;
if (error instanceof S3ServiceException) {
// Don't retry certain errors
const nonRetryableErrors = [
"NoSuchBucket",
"NoSuchKey",
"AccessDenied",
"InvalidRequest"
];
if (nonRetryableErrors.includes(error.name)) {
console.error(`Non-retryable error: ${error.name}`);
throw error;
}
// Retry server errors and throttling
const retryableErrors = [
"ServiceUnavailable",
"SlowDown",
"RequestTimeout"
];
if (retryableErrors.includes(error.name) && attempt < maxRetries) {
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
console.warn(`Attempt ${attempt} failed: ${error.name}. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
}
if (attempt === maxRetries) {
console.error(`All ${maxRetries} attempts failed. Last error:`, lastError.message);
throw lastError;
}
}
}
throw lastError!;
}
// Error handling with custom error wrapper
class S3OperationError extends Error {
constructor(
message: string,
public operation: string,
public bucket: string,
public key?: string,
public originalError?: Error
) {
super(message);
this.name = "S3OperationError";
}
}
async function safeS3Operation<T>(
operation: string,
bucket: string,
key: string | undefined,
fn: () => Promise<T>
): Promise<T> {
try {
return await fn();
} catch (error) {
if (error instanceof S3ServiceException) {
const message = `${operation} failed: ${error.name} - ${error.message}`;
throw new S3OperationError(message, operation, bucket, key, error);
}
throw error;
}
}
// Usage with custom error wrapper
async function uploadSafely(bucket: string, key: string, content: string) {
return safeS3Operation("upload", bucket, key, async () => {
const command = new PutObjectCommand({
Bucket: bucket,
Key: key,
Body: content
});
return await client.send(command);
});
}
// Error handling with detailed logging
async function handleS3Error(error: unknown, context: string) {
if (error instanceof S3ServiceException) {
const errorDetails = {
context,
errorName: error.name,
errorMessage: error.message,
statusCode: error.$metadata.httpStatusCode,
requestId: error.$metadata.requestId,
retryable: error.$retryable?.throttling || false,
timestamp: new Date().toISOString()
};
console.error("S3 Operation Failed:", JSON.stringify(errorDetails, null, 2));
// Log to monitoring service (example)
// await logToMonitoring(errorDetails);
return errorDetails;
} else {
console.error(`Non-S3 error in ${context}:`, error);
return { context, error: String(error), timestamp: new Date().toISOString() };
}
}
// Example usage with comprehensive error handling
async function robustS3Upload(bucket: string, key: string, content: string) {
try {
return await uploadSafely(bucket, key, content);
} catch (error) {
await handleS3Error(error, `upload:${bucket}/${key}`);
if (error instanceof S3OperationError && error.originalError instanceof S3ServiceException) {
// Provide user-friendly error messages
switch (error.originalError.name) {
case "NoSuchBucket":
throw new Error(`Bucket '${bucket}' does not exist. Please create it first.`);
case "AccessDenied":
throw new Error(`Access denied for bucket '${bucket}'. Check your permissions.`);
case "InvalidBucketName":
throw new Error(`Invalid bucket name '${bucket}'. Check naming requirements.`);
default:
throw new Error(`Upload failed: ${error.message}`);
}
}
throw error;
}
}