Azure: Translate not-found errors in ADLSInputStream mid-stream reads
- Dominant language
- Java
- Stars
- 9.2k
- Forks
- 3.5k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 132
Description
**Apache Iceberg version**
main @ 035fc1e40
**Query engine**
N/A — engine-agnostic (org.apache.iceberg.azure.adlsv2.ADLSInputStream)
**Please describe the bug**
`ADLSInputStream.read()` and `read(byte[], int, int)` (azure/src/main/java/org/apache/iceberg/azure/adlsv2/ADLSInputStream.java, lines 113-146) call `stream.read(...)` directly and let the raw `IOException` propagate when the underlying file is deleted after the stream was opened (for example by a concurrent orphan-file cleanup or snapshot expiration). `openRange()` (same file, lines 199-208) already translates this into `NotFoundException` via `throwNotFoundIfNotPresent`, and `GCSInputStream.read()`/`read(byte[], int, int)` (gcp/src/main/java/org/apache/iceberg/gcp/gcs/GCSInputStream.java, lines 66-98) already does the same for GCS. This is a leftover gap from issue #13528 ("Inconsistent handling of non-existent object locations across FileIO implementations", fixed by PR #15806/#15734), which addressed `openRange`/`readFully`/`readTail` but not the mid-stream `read` methods.
The Azure SDK's `BlobInputStream.dispatchRead` wraps `BlobStorageException` inside `IOException` (`catch (BlobStorageException e) { throw new IOException(e); }`), so the fix must `catch (IOException e)` and pass `e.getCause()` to `throwNotFoundIfNotPresent`, matching the GCS pattern.
**Steps to reproduce**
1. Open an `ADLSInputStream` for an existing ADLS Gen2 file.
2. Delete the underlying file/blob (e.g. concurrent cleanup) after the stream is opened.
3. Call `read()` or `read(byte[], int, int)`.
Expected: `NotFoundException`. Actual: raw `IOException` wrapping `BlobStorageException`/`DataLakeStorageException`.
**Additional context**
N/A — code path fully described above.
Contributor guide
Research direction
Start with azure/src/main/java/org/apache/iceberg/azure/adlsv2/ADLSInputStream.java, focusing on read() and read(byte[], int, int), then compare the corresponding handling in gcp/src/main/java/org/apache/iceberg/gcp/gcs/GCSInputStream.java. Run the relevant Azure module tests or reproduce deletion after opening a stream. Done means mid-stream missing-file errors surface as NotFoundException rather than a raw IOException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, java
- Domain
- cloud
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100