Skip to content

[http] IOClient doc comment incorrectly states that non-2xx responses throw ClientException #1947

Description

@EchoEllet

This doc comment suggests that IOClient throws ClientException in case of a non-2xx HTTP status code (such as 404).

However, that's not the case with http and most BaseClient implementations including cupertino_http, ok_http and BrowserClient.

Try running this (when using using top-level functions):

import 'package:http/http.dart' as http;

void main() async {
  final response = await http.get(Uri.https('dart.dev', '_404'));
  print(response.statusCode);
}

Or when using a Client instance:

import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';

void main(List<String> args) async {
  final http.Client client = IOClient();

  try {
    final response = await client.get(Uri.https('dart.dev', '_404'));
    print(response.statusCode);
  } finally {
    client.close();
  }
}

In either case, statusCode is 404 and no exception was thrown (assuming dart.dev is reachable).

More details

it seems that IOClient throws _ClientException that extends ClientException and implements SocketException (code) to avoid breaking existing consumers that handle SocketException.

ClientException hides OSError (from dart:io) and other platform-specific details from SocketException.

_ClientException implements SocketException in a compatible manner, allowing consumers to handle these details (e.g., when using conditional imports to support web) when needed.

NSErrorClientException extends ClientException.

In most cases, consumers of the http should consider handling ClientException unless they need internal SocketException details (does not work on the web). Most apps do not need to.

try {
  data = await client.read(Uri.https('example.com', ''));
} on http.ClientException catch (e) {
  // Exception is transport-related.
  //
  // If platform-specific socket details are needed, catch `SocketException`
  // before `ClientException` (or without `ClientException`) and inspect `osError` for additional information.
  //
  // If the handler for `SocketException` were removed, then all exceptions
  // would be caught by this handler.
}

This would keep the handling implementation independent (BrowserClient, IOClient, CupertinoClient, OkHttpClient, WinHttpClient, FetchClient, RhttpCompatibleClient), which works on the web as well.

Implementation-specific exceptions can still be handled when internal details are needed (e.g., OSError, NSError).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions