PDGGK opened a new pull request, #37342:
URL: https://github.com/apache/beam/pull/37342
## Summary
Fixes #37176 - RequestResponseIO parseAndThrow wraps retryable exceptions
The `parseAndThrow` method in `Call.java` was wrapping retryable exceptions
(`UserCodeTimeoutException`, `UserCodeRemoteSystemException`) in a generic
`UserCodeExecutionException`, which broke the retry logic that depends on
`exception.shouldRepeat()`.
### Root Cause
When `parseAndThrow` caught an `ExecutionException`, it only checked the
direct cause. If the cause was a generic exception wrapping a retryable one, it
would throw the generic wrapper, losing the retryable behavior.
### Solution
- Use Guava's `Throwables.getCausalChain()` to traverse the full exception
chain
- Preserve all retryable exception types: `UserCodeQuotaException`,
`UserCodeTimeoutException`, `UserCodeRemoteSystemException`
- Prefer specific exception types over generic ones to prevent masking
- Handle circular references gracefully
### Changes
**Modified:**
-
`sdks/java/io/rrio/src/main/java/org/apache/beam/io/requestresponse/Call.java`
- Rewrote `parseAndThrow` method
**Added Tests:**
- `CallTest.java` - Added 10 comprehensive tests covering:
- Direct retryable exceptions
- Nested exceptions (multiple wrapper layers)
- Triple-nested exceptions
- Generic exceptions wrapping retryable ones
- Circular reference handling
- Non-UserCode exceptions
### Test Results
All tests pass:
- ✅ Existing CallTest suite
- ✅ 10 new tests for exception handling
- ✅ Full rrio module tests
- ✅ Code formatting (spotless)
## Test plan
- [x] Unit tests added for all edge cases
- [x] Existing tests continue to pass
- [x] Code formatting verified
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]