Problem
In main.go lines 105–109, the S3 object body is closed manually but not with defer:
bodyBytes, err := io.ReadAll(getObjectOutput.Body)
getObjectOutput.Body.Close()
if err != nil {
return fmt.Errorf("failed to read S3 object body: %w", err)
}
If io.ReadAll returns an error, Close() is still called. However, the pattern is fragile:
- If any code is added between
GetObject and io.ReadAll that could panic or return early, the body would leak.
- The
Close() error is ignored — a failed close could indicate incomplete reads or connection issues.
- This doesn't follow the idiomatic Go pattern of
defer body.Close() immediately after acquisition.
Proposed Solution
Use defer immediately after acquiring the body:
getObjectOutput, err := s3Client.GetObject(ctx, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return fmt.Errorf("failed to fetch object %s/%s: %w", bucket, key, err)
}
defer getObjectOutput.Body.Close()
bodyBytes, err := io.ReadAll(getObjectOutput.Body)
if err != nil {
return fmt.Errorf("failed to read S3 object body: %w", err)
}
Acceptance Criteria
Problem
In main.go lines 105–109, the S3 object body is closed manually but not with
defer:If
io.ReadAllreturns an error,Close()is still called. However, the pattern is fragile:GetObjectandio.ReadAllthat could panic or return early, the body would leak.Close()error is ignored — a failed close could indicate incomplete reads or connection issues.defer body.Close()immediately after acquisition.Proposed Solution
Use
deferimmediately after acquiring the body:Acceptance Criteria
io.ReadCloserbodies from S3 are closed viadefer