Skip to content

Commit fa3461b

Browse files
brianquinlanCommit Queue
authored andcommitted
[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:#60161 Change-Id: I27a6a81be7a83fe2fa0cbbdaf040af3f7fa38f13 Tested: unit tests Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412184 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Brian Quinlan <[email protected]>
1 parent 1cb6dd0 commit fa3461b

File tree

3 files changed

+81
-52
lines changed

3 files changed

+81
-52
lines changed

sdk/lib/_internal/vm/bin/socket_patch.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,12 @@ base class _NativeSocket extends _NativeSocketNativeWrapper
11561156
onTimeout: () {
11571157
task.cancel();
11581158
throw createError(
1159-
null,
1159+
OSError(
1160+
"Connection timed out",
1161+
Platform.isWindows
1162+
? 10060 // WSAETIMEDOUT
1163+
: 110, // ETIMEDOUT
1164+
),
11601165
"Connection timed out, host: ${host}, port: ${port}",
11611166
);
11621167
},

tests/standalone/io/secure_socket_test.dart

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,39 @@ String localFile(path) => Platform.script.resolve(path).toFilePath();
2323

2424
SecurityContext serverContext(String certType, String password) =>
2525
new SecurityContext()
26-
..useCertificateChain(localFile('certificates/server_chain.$certType'),
27-
password: password)
28-
..usePrivateKey(localFile('certificates/server_key.$certType'),
29-
password: password);
26+
..useCertificateChain(
27+
localFile('certificates/server_chain.$certType'),
28+
password: password,
29+
)
30+
..usePrivateKey(
31+
localFile('certificates/server_key.$certType'),
32+
password: password,
33+
);
3034

3135
SecurityContext clientContext(String certType, String password) =>
32-
new SecurityContext()
33-
..setTrustedCertificates(
34-
localFile('certificates/trusted_certs.$certType'),
35-
password: password);
36+
new SecurityContext()..setTrustedCertificates(
37+
localFile('certificates/trusted_certs.$certType'),
38+
password: password,
39+
);
3640

3741
Future<HttpServer> startServer(String certType, String password) {
3842
return HttpServer.bindSecure(
39-
"localhost", 0, serverContext(certType, password),
40-
backlog: 5)
41-
.then((server) {
43+
"localhost",
44+
0,
45+
serverContext(certType, password),
46+
backlog: 5,
47+
).then((server) {
4248
server.listen((HttpRequest request) {
43-
request.listen((_) {}, onDone: () {
44-
request.response.contentLength = 100;
45-
for (int i = 0; i < 10; i++) {
46-
request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
47-
}
48-
request.response.close();
49-
});
49+
request.listen(
50+
(_) {},
51+
onDone: () {
52+
request.response.contentLength = 100;
53+
for (int i = 0; i < 10; i++) {
54+
request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
55+
}
56+
request.response.close();
57+
},
58+
);
5059
});
5160
return server;
5261
});
@@ -56,40 +65,49 @@ Future test(String certType, String password) {
5665
List<int> body = <int>[];
5766
Completer completer = new Completer();
5867
startServer(certType, password).then((server) {
59-
SecureSocket.connect("localhost", server.port,
60-
context: clientContext(certType, password))
61-
.then((socket) {
68+
SecureSocket.connect(
69+
"localhost",
70+
server.port,
71+
context: clientContext(certType, password),
72+
).then((socket) {
6273
socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
6374
socket.close();
64-
socket.listen((List<int> data) {
65-
body.addAll(data);
66-
}, onDone: () {
67-
Expect.isTrue(body.length > 100, "$body\n${body.length}");
68-
Expect.equals(72, body[0]);
69-
Expect.equals(9, body[body.length - 1]);
70-
server.close();
71-
completer.complete(null);
72-
}, onError: (e, trace) {
73-
String msg = "Unexpected error $e";
74-
if (trace != null) msg += "\nStackTrace: $trace";
75-
Expect.fail(msg);
76-
completer.complete(null);
77-
});
75+
socket.listen(
76+
(List<int> data) {
77+
body.addAll(data);
78+
},
79+
onDone: () {
80+
Expect.isTrue(body.length > 100, "$body\n${body.length}");
81+
Expect.equals(72, body[0]);
82+
Expect.equals(9, body[body.length - 1]);
83+
server.close();
84+
completer.complete(null);
85+
},
86+
onError: (e, trace) {
87+
String msg = "Unexpected error $e";
88+
if (trace != null) msg += "\nStackTrace: $trace";
89+
Expect.fail(msg);
90+
completer.complete(null);
91+
},
92+
);
7893
});
7994
});
8095
return completer.future;
8196
}
8297

8398
void testConnectTimeout() {
8499
asyncStart();
85-
Duration timeout = new Duration(milliseconds: 20);
86-
SecureSocket.connect("8.8.8.7", 80, timeout: timeout).then((socket) {
87-
Expect.fail("Unexpected connection made.");
88-
asyncEnd();
89-
}).catchError((e) {
90-
Expect.isTrue(e is SocketException);
91-
asyncEnd();
92-
});
100+
Duration timeout = new Duration(milliseconds: 0);
101+
SecureSocket.connect("8.8.8.7", 80, timeout: timeout)
102+
.then((socket) {
103+
Expect.fail("Unexpected connection made.");
104+
asyncEnd();
105+
})
106+
.catchError((e) {
107+
Expect.isTrue(e is SocketException);
108+
Expect.equals(Platform.isWindows? 10060 : 110, (e as SocketException).osError?.errorCode);
109+
asyncEnd();
110+
});
93111
}
94112

95113
main() async {

tests/standalone/io/socket_connect_timeout_test.dart

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ import "package:expect/expect.dart";
1515

1616
void main() {
1717
asyncStart();
18-
Duration timeout = new Duration(milliseconds: 20);
19-
Socket.connect("8.8.8.7", 80, timeout: timeout).then((socket) {
20-
Expect.fail("Unexpected connection made.");
21-
asyncEnd();
22-
}).catchError((e) {
23-
Expect.isTrue(e is SocketException);
24-
asyncEnd();
25-
});
18+
Duration timeout = new Duration(milliseconds: 0);
19+
Socket.connect("8.8.8.7", 80, timeout: timeout)
20+
.then((socket) {
21+
Expect.fail("Unexpected connection made.");
22+
asyncEnd();
23+
})
24+
.catchError((e) {
25+
Expect.isTrue(e is SocketException);
26+
Expect.equals(
27+
Platform.isWindows ? 10060 : 110,
28+
(e as SocketException).osError?.errorCode,
29+
);
30+
asyncEnd();
31+
});
2632
}

0 commit comments

Comments
 (0)