mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:49:47 +00:00
[ VM / dart:io ] Adding to a closed IOSink now throws a StateError
Based off of these original changes: https://codereview.chromium.org/2857393003 This is a breaking change and will require an annoucement stating such before landing. Fixes #29554. Change-Id: Ibb56fd49648edc6b9fd567240a3bebb05a14234d Reviewed-on: https://dart-review.googlesource.com/c/90120 Commit-Queue: Ben Konyi <bkonyi@google.com> Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
parent
983b77dda7
commit
bb560bb233
|
@ -43,6 +43,9 @@
|
||||||
#### `dart:io`
|
#### `dart:io`
|
||||||
|
|
||||||
* Added ability to get and set low level socket options.
|
* Added ability to get and set low level socket options.
|
||||||
|
* **Breaking Change:** Adding to a closed `IOSink` now throws a `StateError`.
|
||||||
|
|
||||||
|
[29554]: https://github.com/dart-lang/sdk/issues/29554
|
||||||
|
|
||||||
### Dart VM
|
### Dart VM
|
||||||
|
|
||||||
|
|
|
@ -531,24 +531,16 @@ class _StreamSinkImpl<T> implements StreamSink<T> {
|
||||||
|
|
||||||
_StreamSinkImpl(this._target);
|
_StreamSinkImpl(this._target);
|
||||||
|
|
||||||
void _reportClosedSink() {
|
|
||||||
stderr.writeln("StreamSink is closed and adding to it is an error.");
|
|
||||||
stderr.writeln(" See http://dartbug.com/29554.");
|
|
||||||
stderr.writeln(StackTrace.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(T data) {
|
void add(T data) {
|
||||||
if (_isClosed) {
|
if (_isClosed) {
|
||||||
_reportClosedSink();
|
throw StateError("StreamSink is closed");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_controller.add(data);
|
_controller.add(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addError(error, [StackTrace stackTrace]) {
|
void addError(error, [StackTrace stackTrace]) {
|
||||||
if (_isClosed) {
|
if (_isClosed) {
|
||||||
_reportClosedSink();
|
throw StateError("StreamSink is closed");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_controller.addError(error, stackTrace);
|
_controller.addError(error, stackTrace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,17 +220,9 @@ class _HandlerEventSink<S, T> implements EventSink<S> {
|
||||||
|
|
||||||
bool get _isClosed => _sink == null;
|
bool get _isClosed => _sink == null;
|
||||||
|
|
||||||
_reportClosedSink() {
|
|
||||||
// TODO(29554): throw a StateError, and don't just report the problem.
|
|
||||||
Zone.root
|
|
||||||
..print("Sink is closed and adding to it is an error.")
|
|
||||||
..print(" See http://dartbug.com/29554.")
|
|
||||||
..print(StackTrace.current.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(S data) {
|
void add(S data) {
|
||||||
if (_isClosed) {
|
if (_isClosed) {
|
||||||
_reportClosedSink();
|
throw StateError("Sink is closed");
|
||||||
}
|
}
|
||||||
if (_handleData != null) {
|
if (_handleData != null) {
|
||||||
_handleData(data, _sink);
|
_handleData(data, _sink);
|
||||||
|
@ -241,7 +233,7 @@ class _HandlerEventSink<S, T> implements EventSink<S> {
|
||||||
|
|
||||||
void addError(Object error, [StackTrace stackTrace]) {
|
void addError(Object error, [StackTrace stackTrace]) {
|
||||||
if (_isClosed) {
|
if (_isClosed) {
|
||||||
_reportClosedSink();
|
throw StateError("Sink is closed");
|
||||||
}
|
}
|
||||||
if (_handleError != null) {
|
if (_handleError != null) {
|
||||||
_handleError(error, stackTrace, _sink);
|
_handleError(error, stackTrace, _sink);
|
||||||
|
|
|
@ -149,32 +149,16 @@ class _StreamSinkImpl<T> implements StreamSink<T> {
|
||||||
|
|
||||||
_StreamSinkImpl(this._target);
|
_StreamSinkImpl(this._target);
|
||||||
|
|
||||||
void _reportClosedSink() {
|
|
||||||
// TODO(29554): this is very brittle and depends on the layout of the
|
|
||||||
// stderr class.
|
|
||||||
if (this == stderr._sink) {
|
|
||||||
// We can't report on stderr anymore (as we would otherwise
|
|
||||||
// have an infinite recursion.
|
|
||||||
throw new StateError("Stderr is closed.");
|
|
||||||
}
|
|
||||||
// TODO(29554): throw a StateError, and don't just report the problem.
|
|
||||||
stderr.writeln("StreamSink is closed and adding to it is an error.");
|
|
||||||
stderr.writeln(" See http://dartbug.com/29554.");
|
|
||||||
stderr.writeln(StackTrace.current);
|
|
||||||
}
|
|
||||||
|
|
||||||
void add(T data) {
|
void add(T data) {
|
||||||
if (_isClosed) {
|
if (_isClosed) {
|
||||||
_reportClosedSink();
|
throw StateError("StreamSink is closed");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_controller.add(data);
|
_controller.add(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addError(error, [StackTrace stackTrace]) {
|
void addError(error, [StackTrace stackTrace]) {
|
||||||
if (_isClosed) {
|
if (_isClosed) {
|
||||||
_reportClosedSink();
|
throw StateError("StreamSink is closed");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_controller.addError(error, stackTrace);
|
_controller.addError(error, stackTrace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1367,7 +1367,6 @@ LibTest/io/HttpClientBasicCredentials/HttpClientBasicCredentials_A01_t01: Runtim
|
||||||
LibTest/io/HttpClientDigestCredentials/HttpClientDigestCredentials_A01_t01: RuntimeError
|
LibTest/io/HttpClientDigestCredentials/HttpClientDigestCredentials_A01_t01: RuntimeError
|
||||||
LibTest/io/HttpClientRequest/addStream_A02_t02: RuntimeError
|
LibTest/io/HttpClientRequest/addStream_A02_t02: RuntimeError
|
||||||
LibTest/io/HttpClientRequest/add_A03_t01: RuntimeError
|
LibTest/io/HttpClientRequest/add_A03_t01: RuntimeError
|
||||||
LibTest/io/HttpClientRequest/close_A02_t01: RuntimeError
|
|
||||||
LibTest/io/HttpClientRequest/done_A02_t01: RuntimeError, Timeout, Pass
|
LibTest/io/HttpClientRequest/done_A02_t01: RuntimeError, Timeout, Pass
|
||||||
LibTest/io/HttpClientResponse/certificate_A01_t01: RuntimeError
|
LibTest/io/HttpClientResponse/certificate_A01_t01: RuntimeError
|
||||||
LibTest/io/HttpClientResponse/isRedirect_A01_t02: RuntimeError
|
LibTest/io/HttpClientResponse/isRedirect_A01_t02: RuntimeError
|
||||||
|
|
|
@ -47,7 +47,7 @@ void clientSocketExceptionTest() {
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
wrongExceptionCaught = true;
|
wrongExceptionCaught = true;
|
||||||
}
|
}
|
||||||
Expect.isFalse(exceptionCaught);
|
Expect.isTrue(exceptionCaught);
|
||||||
Expect.isFalse(wrongExceptionCaught);
|
Expect.isFalse(wrongExceptionCaught);
|
||||||
|
|
||||||
// From here exceptions are expected.
|
// From here exceptions are expected.
|
||||||
|
|
|
@ -988,7 +988,9 @@ class FileTest {
|
||||||
file.createSync();
|
file.createSync();
|
||||||
var output = file.openWrite();
|
var output = file.openWrite();
|
||||||
output.close();
|
output.close();
|
||||||
output.add(buffer); // Ignored.
|
Expect.throws(() {
|
||||||
|
output.add(buffer);
|
||||||
|
});
|
||||||
output.done.then((_) {
|
output.done.then((_) {
|
||||||
file.deleteSync();
|
file.deleteSync();
|
||||||
asyncTestDone("testCloseExceptionStream");
|
asyncTestDone("testCloseExceptionStream");
|
||||||
|
|
|
@ -29,7 +29,9 @@ void testHttp10NoKeepAlive() {
|
||||||
response.write("Z");
|
response.write("Z");
|
||||||
response.write("Z");
|
response.write("Z");
|
||||||
response.close();
|
response.close();
|
||||||
response.write("x");
|
Expect.throws(() {
|
||||||
|
response.write("x");
|
||||||
|
}, (e) => e is StateError);
|
||||||
}, onError: (e, trace) {
|
}, onError: (e, trace) {
|
||||||
String msg = "Unexpected error $e";
|
String msg = "Unexpected error $e";
|
||||||
if (trace != null) msg += "\nStackTrace: $trace";
|
if (trace != null) msg += "\nStackTrace: $trace";
|
||||||
|
|
|
@ -37,7 +37,9 @@ void testNoBody(int totalConnections, bool explicitContentLength) {
|
||||||
// After an explicit close, write becomes a state error
|
// After an explicit close, write becomes a state error
|
||||||
// because we have said we will not add more.
|
// because we have said we will not add more.
|
||||||
response.close();
|
response.close();
|
||||||
response.write("x");
|
Expect.throws(() {
|
||||||
|
response.write("x");
|
||||||
|
}, (e) => e is StateError);
|
||||||
}, onError: (e, trace) {
|
}, onError: (e, trace) {
|
||||||
String msg = "Unexpected server error $e";
|
String msg = "Unexpected server error $e";
|
||||||
if (trace != null) msg += "\nStackTrace: $trace";
|
if (trace != null) msg += "\nStackTrace: $trace";
|
||||||
|
@ -89,7 +91,9 @@ void testBody(int totalConnections, bool useHeader) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
response.close();
|
response.close();
|
||||||
response.write("x");
|
Expect.throws(() {
|
||||||
|
response.write("x");
|
||||||
|
}, (e) => e is StateError);
|
||||||
});
|
});
|
||||||
}, onError: (e, trace) {
|
}, onError: (e, trace) {
|
||||||
String msg = "Unexpected error $e";
|
String msg = "Unexpected error $e";
|
||||||
|
@ -149,7 +153,9 @@ void testBodyChunked(int totalConnections, bool useHeader) {
|
||||||
response.write("x");
|
response.write("x");
|
||||||
response.write("x");
|
response.write("x");
|
||||||
response.close();
|
response.close();
|
||||||
response.write("x");
|
Expect.throws(() {
|
||||||
|
response.write("x");
|
||||||
|
}, (e) => e is StateError);
|
||||||
});
|
});
|
||||||
}, onError: (e, trace) {
|
}, onError: (e, trace) {
|
||||||
String msg = "Unexpected error $e";
|
String msg = "Unexpected error $e";
|
||||||
|
|
|
@ -164,7 +164,9 @@ void test(bool hostnameInConnect, bool handshakeBeforeSecure,
|
||||||
SecureSocket.secure(socket, host: HOST, context: clientContext);
|
SecureSocket.secure(socket, host: HOST, context: clientContext);
|
||||||
}
|
}
|
||||||
return future.then<SecureSocket>((SecureSocket secureSocket) {
|
return future.then<SecureSocket>((SecureSocket secureSocket) {
|
||||||
socket.add([0]);
|
Expect.throws(() {
|
||||||
|
socket.add([0]);
|
||||||
|
});
|
||||||
return secureSocket;
|
return secureSocket;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -179,7 +181,9 @@ void test(bool hostnameInConnect, bool handshakeBeforeSecure,
|
||||||
SecureSocket.secure(socket, host: HOST, context: clientContext);
|
SecureSocket.secure(socket, host: HOST, context: clientContext);
|
||||||
}
|
}
|
||||||
return future.then((secureSocket) {
|
return future.then((secureSocket) {
|
||||||
socket.add([0]);
|
Expect.throws(() {
|
||||||
|
socket.add([0]);
|
||||||
|
});
|
||||||
return secureSocket;
|
return secureSocket;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -191,7 +195,9 @@ void test(bool hostnameInConnect, bool handshakeBeforeSecure,
|
||||||
server.listen((client) {
|
server.listen((client) {
|
||||||
if (!handshakeBeforeSecure) {
|
if (!handshakeBeforeSecure) {
|
||||||
SecureSocket.secureServer(client, serverContext).then((secureClient) {
|
SecureSocket.secureServer(client, serverContext).then((secureClient) {
|
||||||
client.add([0]);
|
Expect.throws(() {
|
||||||
|
client.add([0]);
|
||||||
|
});
|
||||||
runServer(secureClient).then((_) => server.close());
|
runServer(secureClient).then((_) => server.close());
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -199,7 +205,9 @@ void test(bool hostnameInConnect, bool handshakeBeforeSecure,
|
||||||
SecureSocket
|
SecureSocket
|
||||||
.secureServer(client, serverContext, bufferedData: carryOverData)
|
.secureServer(client, serverContext, bufferedData: carryOverData)
|
||||||
.then((secureClient) {
|
.then((secureClient) {
|
||||||
client.add([0]);
|
Expect.throws(() {
|
||||||
|
client.add([0]);
|
||||||
|
});
|
||||||
runServer(secureClient).then((_) => server.close());
|
runServer(secureClient).then((_) => server.close());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue