Skip to content

Commit 8a4a4a6

Browse files
authored
Add a better toString to _ClientSocketException (#948)
1 parent 5c1f1ad commit 8a4a4a6

File tree

6 files changed

+53
-6
lines changed

6 files changed

+53
-6
lines changed

pkgs/http/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.0.1
2+
3+
* Add better error messages for `SocketException`s when using `IOClient`.
4+
15
## 1.0.0
26

37
* Requires Dart 3.0 or later.

pkgs/http/lib/src/client.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import 'streamed_response.dart';
2525
/// [http.head], [http.get], [http.post], [http.put], [http.patch], or
2626
/// [http.delete] instead.
2727
///
28+
/// All methods will emit a [ClientException] if there is a transport-level
29+
/// failure when communication with the server. For example, if the server could
30+
/// not be reached.
31+
///
2832
/// When creating an HTTP client class with additional functionality, you must
2933
/// extend [BaseClient] rather than [Client]. In most cases, you can wrap
3034
/// another instance of [Client] and add functionality on top of that. This

pkgs/http/lib/src/exception.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,11 @@ class ClientException implements Exception {
1212
ClientException(this.message, [this.uri]);
1313

1414
@override
15-
String toString() => message;
15+
String toString() {
16+
if (uri != null) {
17+
return 'ClientException: $message, uri=$uri';
18+
} else {
19+
return 'ClientException: $message';
20+
}
21+
}
1622
}

pkgs/http/lib/src/io_client.dart

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:io';
66

77
import 'base_client.dart';
88
import 'base_request.dart';
9+
import 'client.dart';
910
import 'exception.dart';
1011
import 'io_streamed_response.dart';
1112

@@ -28,9 +29,9 @@ BaseClient createClient() {
2829
class _ClientSocketException extends ClientException
2930
implements SocketException {
3031
final SocketException cause;
31-
_ClientSocketException(SocketException e, Uri url)
32+
_ClientSocketException(SocketException e, Uri uri)
3233
: cause = e,
33-
super(e.message, url);
34+
super(e.message, uri);
3435

3536
@override
3637
InternetAddress? get address => cause.address;
@@ -40,9 +41,33 @@ class _ClientSocketException extends ClientException
4041

4142
@override
4243
int? get port => cause.port;
44+
45+
@override
46+
String toString() => 'ClientException with $cause, uri=$uri';
4347
}
4448

45-
/// A `dart:io`-based HTTP client.
49+
/// A `dart:io`-based HTTP [Client].
50+
///
51+
/// If there is a socket-level failure when communicating with the server
52+
/// (for example, if the server could not be reached), [IOClient] will emit a
53+
/// [ClientException] that also implements [SocketException]. This allows
54+
/// callers to get more detailed exception information for socket-level
55+
/// failures, if desired.
56+
///
57+
/// For example:
58+
/// ```dart
59+
/// final client = http.Client();
60+
/// late String data;
61+
/// try {
62+
/// data = await client.read(Uri.https('example.com', ''));
63+
/// } on SocketException catch (e) {
64+
/// // Exception is transport-related, check `e.osError` for more details.
65+
/// } on http.ClientException catch (e) {
66+
/// // Exception is HTTP-related (e.g. the server returned a 404 status code).
67+
/// // If the handler for `SocketException` were removed then all exceptions
68+
/// // would be caught by this handler.
69+
/// }
70+
/// ```
4671
class IOClient extends BaseClient {
4772
/// The underlying `dart:io` HTTP client.
4873
HttpClient? _inner;

pkgs/http/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: http
2-
version: 1.0.0
2+
version: 1.0.1-wip
33
description: A composable, multi-platform, Future-based API for HTTP requests.
44
repository: https://github.com/dart-lang/http/tree/master/pkgs/http
55

pkgs/http/test/io/client_test.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,15 @@ void main() {
118118
request.headers[HttpHeaders.contentTypeHeader] =
119119
'application/json; charset=utf-8';
120120

121-
expect(client.send(request), throwsA(isA<SocketException>()));
121+
expect(
122+
client.send(request),
123+
throwsA(allOf(
124+
isA<http.ClientException>().having((e) => e.uri, 'uri', url),
125+
isA<SocketException>().having(
126+
(e) => e.toString(),
127+
'SocketException.toString',
128+
matches('ClientException with SocketException.*,'
129+
' uri=http://http.invalid')))));
122130

123131
request.sink.add('{"hello": "world"}'.codeUnits);
124132
request.sink.close();

0 commit comments

Comments
 (0)