Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions pkgs/http/lib/src/io_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,16 @@ class _IOStreamedResponseV2 extends IOStreamedResponse
/// callers to get more detailed exception information for socket-level
/// failures, if desired.
///
/// For example:
/// Example:
/// ```dart
/// final client = http.Client();
/// final client = IOClient();
/// late String data;
/// try {
/// data = await client.read(Uri.https('example.com', ''));
/// } on SocketException catch (e) {
/// // 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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@EchoEllet EchoEllet Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

  1. 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)

  1. When HttpClient from dart:io throws
} 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).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

/// // If platform-specific socket details are needed, catch `SocketException`
/// // before `ClientException` (or without `ClientException`) and inspect `osError` for more details.
/// // If the handler for `SocketException` were removed then all exceptions
/// // would be caught by this handler.
/// }
Expand Down
Loading