HttpPoolManager._executeWithRetry - ClientException/SocketException crash#4525
HttpPoolManager._executeWithRetry - ClientException/SocketException crash#4525
Conversation
…Retry Return synthetic 503 response for SocketException, TimeoutException, ClientException, and HandshakeException instead of throwing fatal errors. Also add HandshakeException to the retry catch list and add logging to sendStreaming. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request aims to fix a crash caused by unhandled network exceptions in HttpPoolManager._executeWithRetry by catching them and returning a synthetic 503 error response. The changes in _executeWithRetry and the addition of HandshakeException to the list of caught exceptions are well-implemented. The modifications to sendStreaming are incomplete and inconsistent with the PR's goal, as they only log and rethrow SocketException, which does not prevent a crash and ignores other network errors. The provided suggestion makes the error handling in sendStreaming robust and consistent with the rest of the changes.
| }) async { | ||
| try { | ||
| return await _client.send(request).timeout(timeout); | ||
| } on SocketException catch (e) { | ||
| Logger.debug('HttpPoolManager sendStreaming SocketException: $e'); | ||
| rethrow; | ||
| } | ||
| } |
There was a problem hiding this comment.
The change in sendStreaming is inconsistent with the PR's goal of preventing crashes from network errors. It only handles SocketException and rethrows it, which means the caller will still crash if the exception is not handled. Furthermore, other potential network exceptions like TimeoutException, http.ClientException, and HandshakeException are not caught at all.
To align with the robust error handling in _executeWithRetry, sendStreaming should also catch all relevant network exceptions and return a synthetic StreamedResponse instead of rethrowing. This will prevent crashes for callers of this method.
| }) async { | |
| try { | |
| return await _client.send(request).timeout(timeout); | |
| } on SocketException catch (e) { | |
| Logger.debug('HttpPoolManager sendStreaming SocketException: $e'); | |
| rethrow; | |
| } | |
| } | |
| }) async { | |
| try { | |
| return await _client.send(request).timeout(timeout); | |
| } on Exception catch (e) { | |
| if (e is SocketException || | |
| e is TimeoutException || | |
| e is http.ClientException || | |
| e is HandshakeException) { | |
| Logger.debug('HttpPoolManager sendStreaming network error: $e'); | |
| return http.StreamedResponse(Stream<List<int>>.empty(), 503, reasonPhrase: 'Network error: $e'); | |
| } | |
| rethrow; | |
| } | |
| } |
Callers expect a StreamedResponse, not an exception. Return a 503 response on SocketException so callers can handle it uniformly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@aaravgarg Quick nudge: tests/demo evidence is required before review. Your crash-fix PRs (#4525–#4549) all have good Crashlytics data and test plans, but the test checkboxes are unchecked. Please add test output or a short screenshot/video showing the fix works, then we can proceed with review. This applies to all PRs in the batch. Thanks! by AI for @beastoin |
Summary
HttpPoolManager._executeWithRetrywhere network errors (SocketException, TimeoutException, ClientException, HandshakeException) are thrown after retry exhaustion, crashing the appHandshakeExceptionto the retry catch list for SSL/TLS errorsCrash Stats
Test plan
🤖 Generated with Claude Code