如何在AWS JavaScript SDK中捕获返回200 OK的S3 copyObject失败
copyObject's 200 OK with Failure Scenarios Let’s break down the AWS documentation and answer your questions clearly, with practical examples:
What the Documentation Is Trying to Say
The key quirk of copyObject is that S3 handles errors in two separate phases, and only one of them follows standard HTTP error patterns:
- Pre-copy errors: These happen before S3 starts the actual copy work—think invalid credentials, a source object that doesn’t exist, or missing permissions to write to the destination bucket. For these, you’ll get a standard 4xx/5xx HTTP error (like
403 Forbiddenor404 Not Found) with the typical S3 error response body. - Mid-copy errors: These occur after S3 has accepted your request and begun copying data. Instead of sending an error status code, S3 returns a
200 OK, but tucks the error details directly into the response body. This means you can’t rely solely on the HTTP status to confirm success.
Real-World Scenarios Where 200 OK Means Copy Failure
Here are concrete examples of when this happens:
- Source object deleted mid-copy: Imagine you’re copying a 15GB video file. Halfway through the transfer, another process deletes the source object. S3 can’t finish the copy, but since it already accepted the request, it returns a
200 OKwith an error stating the source object is no longer available. - KMS key failure during encryption: If your destination bucket requires server-side encryption with a KMS key, and that key gets revoked or goes offline while the copy is in progress. S3 can’t encrypt the destination object, so it sends 200 OK with an error about KMS access issues.
- Cross-region replication interruption: When copying between regions, a transient network outage hits after S3 has started moving data but before completion. Instead of retrying (since
copyObjectisn’t idempotent by default), S3 returns 200 OK with an error about the transfer being interrupted.
How to Detect These Failures in the Node.js SDK
Even though the TypeScript types (CopyObjectResult, S3.Types.CopyObjectOutput) don’t explicitly list these error fields, the SDK still parses the embedded error details into the response object at runtime. Here’s how to handle it:
- Check for success markers: A fully successful copy will always include
ETagandLastModifiedfields in the response. If these are missing (even with a 200 status), something went wrong. - Inspect the raw response data: The SDK includes a hidden
$responseproperty in the result. Inside$response.data, you’ll find error fields likeCodeandMessageif a mid-copy failure occurred. - Fallback to raw XML parsing: For edge cases, you can access the raw response body via
$response.httpResponse.bodyand parse the XML to look for an<Error>element.
Here’s a code example to implement this check:
const { S3Client, CopyObjectCommand } = require("@aws-sdk/client-s3"); const s3Client = new S3Client({ region: "us-east-1" }); async function copyS3Object() { const command = new CopyObjectCommand({ Bucket: "your-destination-bucket", Key: "destination-file.txt", CopySource: "/your-source-bucket/source-file.txt" }); try { const response = await s3Client.send(command); // First, verify success markers exist if (!response.ETag || !response.LastModified) { // Check for embedded errors in the raw response data const rawResponseData = response.$response.data; if (rawResponseData.Code && rawResponseData.Message) { throw new Error(`Copy failed mid-process: ${rawResponseData.Code} - ${rawResponseData.Message}`); } throw new Error("Copy completed but no success confirmation markers found"); } console.log("Copy successful!", response); } catch (err) { // This catches both pre-copy errors and our manually thrown mid-copy errors console.error("Copy failed:", err.message); } } copyS3Object();
If you’re using TypeScript, you’ll need to use type assertions (like response as any) to access the $response property since it’s not included in the official type definitions.
内容的提问来源于stack exchange,提问作者fixermark

