[io] When (SecureSocket|Socket).startConnect fails due to timeout, include a `OSError("Connection timed out", 110)` in the SocketException.
This allows the developer to determine the reason for the failure without parsing the exception message.
Bug:https://github.com/dart-lang/sdk/issues/60161
Change-Id: I27a6a81be7a83fe2fa0cbbdaf040af3f7fa38f13
Tested: unit tests
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412184
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Brian Quinlan <bquinlan@google.com>
diff --git a/sdk/lib/_internal/vm/bin/socket_patch.dart b/sdk/lib/_internal/vm/bin/socket_patch.dart
index 18c3c86..a5ed255 100644
--- a/sdk/lib/_internal/vm/bin/socket_patch.dart
+++ b/sdk/lib/_internal/vm/bin/socket_patch.dart
@@ -1156,7 +1156,12 @@
onTimeout: () {
task.cancel();
throw createError(
- null,
+ OSError(
+ "Connection timed out",
+ Platform.isWindows
+ ? 10060 // WSAETIMEDOUT
+ : 110, // ETIMEDOUT
+ ),
"Connection timed out, host: ${host}, port: ${port}",
);
},
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index 4bef311..687f436 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -23,30 +23,39 @@
SecurityContext serverContext(String certType, String password) =>
new SecurityContext()
- ..useCertificateChain(localFile('certificates/server_chain.$certType'),
- password: password)
- ..usePrivateKey(localFile('certificates/server_key.$certType'),
- password: password);
+ ..useCertificateChain(
+ localFile('certificates/server_chain.$certType'),
+ password: password,
+ )
+ ..usePrivateKey(
+ localFile('certificates/server_key.$certType'),
+ password: password,
+ );
SecurityContext clientContext(String certType, String password) =>
- new SecurityContext()
- ..setTrustedCertificates(
- localFile('certificates/trusted_certs.$certType'),
- password: password);
+ new SecurityContext()..setTrustedCertificates(
+ localFile('certificates/trusted_certs.$certType'),
+ password: password,
+ );
Future<HttpServer> startServer(String certType, String password) {
return HttpServer.bindSecure(
- "localhost", 0, serverContext(certType, password),
- backlog: 5)
- .then((server) {
+ "localhost",
+ 0,
+ serverContext(certType, password),
+ backlog: 5,
+ ).then((server) {
server.listen((HttpRequest request) {
- request.listen((_) {}, onDone: () {
- request.response.contentLength = 100;
- for (int i = 0; i < 10; i++) {
- request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
- }
- request.response.close();
- });
+ request.listen(
+ (_) {},
+ onDone: () {
+ request.response.contentLength = 100;
+ for (int i = 0; i < 10; i++) {
+ request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+ }
+ request.response.close();
+ },
+ );
});
return server;
});
@@ -56,25 +65,31 @@
List<int> body = <int>[];
Completer completer = new Completer();
startServer(certType, password).then((server) {
- SecureSocket.connect("localhost", server.port,
- context: clientContext(certType, password))
- .then((socket) {
+ SecureSocket.connect(
+ "localhost",
+ server.port,
+ context: clientContext(certType, password),
+ ).then((socket) {
socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
socket.close();
- socket.listen((List<int> data) {
- body.addAll(data);
- }, onDone: () {
- Expect.isTrue(body.length > 100, "$body\n${body.length}");
- Expect.equals(72, body[0]);
- Expect.equals(9, body[body.length - 1]);
- server.close();
- completer.complete(null);
- }, onError: (e, trace) {
- String msg = "Unexpected error $e";
- if (trace != null) msg += "\nStackTrace: $trace";
- Expect.fail(msg);
- completer.complete(null);
- });
+ socket.listen(
+ (List<int> data) {
+ body.addAll(data);
+ },
+ onDone: () {
+ Expect.isTrue(body.length > 100, "$body\n${body.length}");
+ Expect.equals(72, body[0]);
+ Expect.equals(9, body[body.length - 1]);
+ server.close();
+ completer.complete(null);
+ },
+ onError: (e, trace) {
+ String msg = "Unexpected error $e";
+ if (trace != null) msg += "\nStackTrace: $trace";
+ Expect.fail(msg);
+ completer.complete(null);
+ },
+ );
});
});
return completer.future;
@@ -82,14 +97,17 @@
void testConnectTimeout() {
asyncStart();
- Duration timeout = new Duration(milliseconds: 20);
- SecureSocket.connect("8.8.8.7", 80, timeout: timeout).then((socket) {
- Expect.fail("Unexpected connection made.");
- asyncEnd();
- }).catchError((e) {
- Expect.isTrue(e is SocketException);
- asyncEnd();
- });
+ Duration timeout = new Duration(milliseconds: 0);
+ SecureSocket.connect("8.8.8.7", 80, timeout: timeout)
+ .then((socket) {
+ Expect.fail("Unexpected connection made.");
+ asyncEnd();
+ })
+ .catchError((e) {
+ Expect.isTrue(e is SocketException);
+ Expect.equals(Platform.isWindows? 10060 : 110, (e as SocketException).osError?.errorCode);
+ asyncEnd();
+ });
}
main() async {
diff --git a/tests/standalone/io/socket_connect_timeout_test.dart b/tests/standalone/io/socket_connect_timeout_test.dart
index 2b3fe97..b2f7175 100644
--- a/tests/standalone/io/socket_connect_timeout_test.dart
+++ b/tests/standalone/io/socket_connect_timeout_test.dart
@@ -15,12 +15,18 @@
void main() {
asyncStart();
- Duration timeout = new Duration(milliseconds: 20);
- Socket.connect("8.8.8.7", 80, timeout: timeout).then((socket) {
- Expect.fail("Unexpected connection made.");
- asyncEnd();
- }).catchError((e) {
- Expect.isTrue(e is SocketException);
- asyncEnd();
- });
+ Duration timeout = new Duration(milliseconds: 0);
+ Socket.connect("8.8.8.7", 80, timeout: timeout)
+ .then((socket) {
+ Expect.fail("Unexpected connection made.");
+ asyncEnd();
+ })
+ .catchError((e) {
+ Expect.isTrue(e is SocketException);
+ Expect.equals(
+ Platform.isWindows ? 10060 : 110,
+ (e as SocketException).osError?.errorCode,
+ );
+ asyncEnd();
+ });
}