| S3BlobStore#deleteDescendants declares BlobStoreException but iterates the listing outside any try block, so a failed ListObjectsV2 throws the SDK's runtime exception, while hasDescendants wraps it. More generally, the streams returned by listDescendants throw implementation-specific unchecked exceptions while iterating (SdkException for S3, UncheckedIOException for the file system), and this is not documented. Proposal: wrap the failure in deleteDescendants; add an API UncheckedBlobStoreException (cause BlobStoreException) thrown by the listing streams of both stores, and document it on listDescendants. |