[http] Fix incorrect IOClient documentation for non-2xx HTTP responses - #1948
[http] Fix incorrect IOClient documentation for non-2xx HTTP responses#1948EchoEllet wants to merge 2 commits into
Conversation
brianquinlan
left a comment
There was a problem hiding this comment.
Thanks for doing this!
| /// // Exception is transport-related, check `e.osError` for more details. | ||
| /// } on http.ClientException catch (e) { | ||
| /// // Exception is HTTP-related (e.g. the server returned a 404 status code). | ||
| /// // Exception is transport-related. |
There was a problem hiding this comment.
The previous comment was false but I don't think that the new comment is correct either. I think that the exception could be transport-related but it could also be HTTP-related, for example a failure to parse the response message. Maybe restore the previous SocketException on-clause and change this to.
// Exception is HTTP-related (e.g. the client could not parse the server's response).Maybe there is a better (or other) example.
There was a problem hiding this comment.
I don't think that the new comment is correct either
I think that the exception could be transport-related but it could also be HTTP-related
Indeed. Some BaseClient implementations may throw ClientException in the event of a TLS handshake error, whereas IOClient (or HttpClient from dart:io) throws TlsException.
// Exception is HTTP-related (e.g. the client could not parse the server's response).
I propose:
// Exception is transport-related (e.g., no internet connection or server is unreachable)
// or HTTP protocol-related (e.g., redirect processing failure, such as a missing
// Location header).Since both io.SocketException and io.HttpException (and by extension io.RedirectException) are mapped to ClientException from the http package.
Maybe restore the previous SocketException on-clause and change this to.
Makes sense. However, I suggest adding a note indicating remove if not needed, since this is already covered by http.ClientException. Many developers assume they need to handle both when seeing the code.
Places that may throw ClientException in IOClient:
- When sending a request after closing the client
/// Sends an HTTP request and asynchronously returns the response.
@override
Future<IOStreamedResponse> send(BaseRequest request) async {
if (_inner == null) {
throw ClientException(
'HTTP request failed. Client is already closed.', request.url);
}
}Maybe it should throw a Dart error (e.g., StateError) instead of ClientException, since this is typically considered a programming bug?
When I sent a PR to flutter/packages, the preferred approach was to use Errors for programming bugs (e.g., flutter/packages#8079)
- When
HttpClientfromdart:iothrows
} on SocketException catch (error) {
throw _ClientSocketException(error, request.url);
} on HttpException catch (error) {
throw ClientException(error.message, error.uri);
}I assume HttpException means something went wrong at the HTTP protocol level.
There is also RedirectException from dart:io:
class RedirectException implements HttpException {
final String message;
final List<RedirectInfo> redirects;
const RedirectException(this.message, this.redirects);
// ...
}Which suggests that an HTTP response was at least received?
I'm not sure if HttpException indicates that a response was received.
In either case, this does not suggest statusCode >= 300 (not a successful response or non-2xx).
Co-authored-by: Brian Quinlan <bquinlan@google.com>
PR Health
Unused Dependencies
|
| Package | Status |
|---|---|
| http | ❗ Show IssuesThese packages may be unused, or you may be using assets from these packages: |
For details on how to fix these, see dependency_validator.
This check can be disabled by tagging the PR with skip-unused-dependencies-check.
Breaking changes ✔️
| Package | Change | Current Version | New Version | Needed Version | Looking good? |
|---|---|---|---|---|---|
| http | None | 1.6.0 | 1.6.1-wip | 1.6.1-wip | ✔️ |
This check can be disabled by tagging the PR with skip-breaking-check.
API leaks ✔️
The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.
| Package | Leaked API symbol | Leaking sources |
|---|
This check can be disabled by tagging the PR with skip-leaking-check.
Changelog Entry ❗
| Package | Changed Files |
|---|---|
| package:http | pkgs/http/lib/src/io_client.dart |
Changes to files need to be accounted for in their respective changelogs.
This check can be disabled by tagging the PR with skip-changelog-check.
Coverage ✔️
| File | Coverage |
|---|---|
| pkgs/http/lib/src/io_client.dart | 💚 89 % |
This check for test coverage is informational (issues shown here will not fail the PR).
This check can be disabled by tagging the PR with skip-coverage-check.
License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
| Files |
|---|
| no missing headers |
All source files should start with a license header.
Unrelated files missing license headers
| Files |
|---|
| pkgs/cupertino_http/example/example.dart |
| pkgs/http/example/main.dart |
| pkgs/http_multi_server/test/cert.dart |
This check can be disabled by tagging the PR with skip-license-check.
|
A bit of context... I introduced try {
data = await client.read(Uri.https('example.com', ''));
} on SocketException catch (e) {
} on http.ClientException catch (e) {
}But, that is not correct for any client other than My expectation is that most applications should just catch
Throwing For Which exception does that apply to? Internet connection issues should be |
|
Thank you for the context.
I agree.
There is an exceptionAs far as I have checked, catching At least in my case, I workarouned this with a conditional import (see also this) to cover TLS failures on IO implementation. Does not appear to be an issue with
I would still consider it or add a comment indicating the reason why this is not a Dart error (e.g., Many applications keep the client open for the lifetime of their application, so it may not even close.
Yes, but |
|
We should probably catch |
|
Sure. Maybe in a separate PR since this is only focused on clarifying the comment. |
| /// // Exception is transport-related, check `e.osError` for more details. | ||
| /// } on http.ClientException catch (e) { | ||
| /// // Exception is HTTP-related (e.g. the server returned a 404 status code). | ||
| /// // Exception is transport-related. |
There was a problem hiding this comment.
Is this always transport-related? How about just remove this line.
And then wrap the next two lines to 80 columns and I'll merge!
Fixes #1947
Contribution guidelines:
dart format.Many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.
Note: The Dart team is trialing Gemini Code Assist. Don't take its comments as final Dart team feedback. Use the suggestions if they're helpful; otherwise, wait for a human reviewer.