Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions be/src/io/fs/s3_obj_storage_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,15 @@ ObjectStorageResponse S3ObjStorageClient::list_objects(const ObjectStoragePathOp
}
if (!outcome.IsSuccess()) {
files->clear();
// Treat NoSuchKey as empty response for compatibility with some S3-compatible storage providers
// e.g. TOS by ByteDance Cloud (Volcano Engine)
if (outcome.GetError().GetErrorType() == Aws::S3::S3Errors::NO_SUCH_KEY) {
LOG(INFO) << "NoSuchKey error when listing objects, treat as empty response"
<< ", prefix=" << opts.prefix
<< ", request_id=" << outcome.GetError().GetRequestId();
return ObjectStorageResponse::OK();
}

return {convert_to_obj_response(s3fs_error(
outcome.GetError(), fmt::format("failed to list {}", opts.prefix))),
static_cast<int>(outcome.GetError().GetResponseCode()),
Expand Down
12 changes: 12 additions & 0 deletions cloud/src/recycler/s3_obj_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ class S3ObjListIterator final : public ObjectListIterator {
const auto& request_id = outcome.IsSuccess() ? outcome.GetResult().GetRequestId()
: outcome.GetError().GetRequestId();
if (!outcome.IsSuccess()) {
// Treat NoSuchKey as empty response for compatibility with some S3-compatible storage providers
// e.g. TOS by ByteDance Cloud (Volcano Engine)
if (outcome.GetError().GetErrorType() == Aws::S3::S3Errors::NO_SUCH_KEY) {
LOG_INFO("NoSuchKey error when listing objects, treat as empty response")
.tag("endpoint", endpoint_)
.tag("bucket", req_.GetBucket())
.tag("prefix", req_.GetPrefix())
.tag("request_id", request_id);
has_more_ = false;
return false;
}

LOG_WARNING("failed to list objects")
.tag("endpoint", endpoint_)
.tag("bucket", req_.GetBucket())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,14 +568,16 @@ private GlobListResult globListInternal(String remotePath, List<RemoteFile> resu
long startTime = System.nanoTime();
String currentMaxFile = "";
boolean hasLimits = fileSizeLimit > 0 || fileNumLimit > 0;
String bucket = "";
String finalPrefix = "";
try {
S3URI uri = S3URI.create(remotePath, isUsePathStyle, forceParsingByStandardUri);
// Directory bucket check for limit scenario
if (hasLimits && uri.useS3DirectoryBucket()) {
throw new RuntimeException("Not support glob with limit for directory bucket");
}

String bucket = uri.getBucket();
bucket = uri.getBucket();
String globPath = S3Util.extendGlobs(uri.getKey());

if (LOG.isDebugEnabled()) {
Expand All @@ -591,7 +593,7 @@ private GlobListResult globListInternal(String remotePath, List<RemoteFile> resu
}

// For Directory Buckets, ensure proper prefix handling using standardized approach
String finalPrefix = listPrefix;
finalPrefix = listPrefix;

if (!hasLimits && uri.useS3DirectoryBucket()) {
String adjustedPrefix = S3URI.getDirectoryPrefixForGlob(listPrefix);
Expand Down Expand Up @@ -678,6 +680,10 @@ private GlobListResult globListInternal(String remotePath, List<RemoteFile> resu
LOG.debug("remotePath:{}, result:{}", remotePath, result);
}
return new GlobListResult(Status.OK, currentMaxFile, bucket, finalPrefix);
} catch (NoSuchKeyException e0) {
LOG.info("NoSuchKey error when listing objects, treat as empty response. bucket={}, prefix={}",
bucket, finalPrefix);
return new GlobListResult(Status.OK, "", bucket, finalPrefix);
} catch (Exception e) {
LOG.warn("Errors while getting file status", e);
return new GlobListResult(new Status(Status.ErrCode.COMMON_ERROR,
Expand Down
Loading