A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | Issue | Example | Current Behavior/Discussion | Change to... | ||||||||||||||||||||||
2 | ||||||||||||||||||||||||||
3 | Different closeCode/closeReason for locally-initiated close | await channel.sink.close(); // Server responds with a close frame. // timing will change the result for dart:html // await Future.delay(const Duration(seconds: 1)); expect(channel.closeCode, ?); expect(channel.closeReason, ?); | dart:html: If closed locally then the values of `channel.closeCode`/`channel.closeReason` will either be null or the server-provided code/reason depending on timing, i.e., whether the JavaScript `onClose` event has been received or not. dart:io: If closed locally, the channel waits up to 5 seconds for the server to respond with a close code/reason and then uses that code/reason for `channel.closeCode`/`channel.closeReason` before completing the `channel.sink.close` future. | Rename `closeCode` to `serverCloseCode`. Rename `closeReason` to `serverCloseReason`. `serverCloseCode` and `serverCloseReason` will always be `null` if `channel.sink.close` is called before a remote close frame is received (or there is a failure e.g. 1006 for a network disconnect). The `channel.stream` will always be done when `serverCloseCode` and `serverCloseReason` are non-null. | ||||||||||||||||||||||
4 | Different closeCode/closeReason for locally-initiated close when the server does not respond quickly with a close frame | await channel.sink.close(4444, 'client initiated'); // Server responds with a close frame after 5s. expect(channel.closeCode, ?); expect(channel.closeReason, ?); | dart:html: The **local** code/reason are used for `channel.closeCode`/`channel.closeReason`. Chrome seems to generate an onClose event with the local code/reason if the server does not respond quickly enough. dart:io: `channel.closeCode`/`channel.closeReason` are `null` | Rename `closeCode` to `serverCloseCode`. Rename `closeReason` to `serverCloseReason`. `serverCloseCode` and `serverCloseReason` will always be `null` if `channel.sink.close` is called before a remote close frame is received (or there is a failure e.g. 1006 for a network disconnect). The `channel.stream` will always be done when `serverCloseCode` and `serverCloseReason` are non-null. | ||||||||||||||||||||||
5 | Different handling of sink.add when the datatype is not supported | channel.sink.add(const Duration(seconds: 5)) | dart:html: Stringifies the Duration and transmits it as text. Stringifies all types except ones that it supports directly, which does *not* include List<int> dart:io: Unhandled exception for all types other than String and List<int> | All implementations must support String (for text frames) and List<int> (for binary frames). Implementations can support other types (e.g. web implementations can suppport Blob). All implementations must throw UnsupportedError for types that they don't understand, i.e., converting them to a string and sending a text frame is not acceptable. If the input is List<int> then ArgumentError must be thrown if any values are >255 or <0. | ||||||||||||||||||||||
6 | Different handling of sink.close() | await channel.sink.close(); expect(await channel.stream.isEmpty, true); | dart:html: When the sink is closed, no new data will be received on the stream but existing data can still be read. The test passes. dart:io: When the sink is closed, the stream is also closed so channel.stream.isEmpty throws a BadStateError | dart:html | ||||||||||||||||||||||
7 | Different handling of sink.add after sink.addError | channel.sink.addError(Exception('what should this do?')); channel.sink.add('Hello World!'); expect(await channel.stream.isEmpty, true); await expectLater(channel.sink.close(), throwsException); | dart:html: nothing is transmitted to the server, unhandled exception, all test expectations met dart:io: nothing is transmitted to the server, unhandled exception, `await channel.stream.isEmpty` never returns IOSink.addError documents "See flush or done for how to get any errors generated by this call.", so getting the exception on .close() might be the expected behavior (though channel.sink is a StreamSink, not an IOSink) But, since there is no reason to call `addError`, just throw UnsupportedError() instead of dealing with this semantic mess. | channel.sink.addError should throw UnsupportedError() and not close `channel.sink`. | ||||||||||||||||||||||
8 | expect(channel.protocol, ?); // Where no protocol was negotiated | dart:html: `channel.protocol` is the empty string dart:io: `channel.protocol` is `null` | dart:io | |||||||||||||||||||||||
9 | Different exception when websocket upgrade not accepted | await expectLater( channel.ready, throwsA(isA<WebSocketChannelException>())); expect(channel.closeCode, null) | dart:html: throws `WebSocketChannelException` (with text "WebSocket connection failed.") as expected. `channel.closeCode` is `null`. An error is sent to channel.stream and channel.stream is closed. dart:io: throws `WebSocketException`, which cannot be caught without importing dart:io. `channel.closeCode` is `null`. No error is sent to channel.stream and channel.stream is not closed. I think that define a common interface that is backwards compatible by ensuring that all exceptions are `WebSocketChannelException` but also implement the dart:io type e.g. class IOWebSocketException extends WebSocketChannelException // Usable on web and VM implements WebSocketException { // Backwards compatible } | channel.ready finishes with a WebSocketChannelException (that may be a subclass of WebSocketException/SocketException) channel.stream is closed. channel.sink.done is complete without error. no error is sent to channel.stream | ||||||||||||||||||||||
10 | Different closeCode when underlying socket disconnected | await expectLater(channel.ready, completes); // Server disconnects the socket immediately after establishing the connection. expect(await channel.stream.isEmpty, true); expect(channel.closeCode, 1006); channel.sink.add('Hello World!'); await channel.sink.close(); | dart:html: `channel.closeCode` is 1006. No error is sent on channel.stream. channel.sink.done is complete. dart:io: `channel.closeCode` is 1005. No error is sent on channel.stream. channel.sink.done is not complete. | Allow close codes to be different. channel.stream is closed. channel.sink.done is complete without error. no error is sent to channel.stream | ||||||||||||||||||||||
11 | ||||||||||||||||||||||||||
12 | ||||||||||||||||||||||||||
13 | ||||||||||||||||||||||||||
14 | ||||||||||||||||||||||||||
15 | ||||||||||||||||||||||||||
16 | ||||||||||||||||||||||||||
17 | ||||||||||||||||||||||||||
18 | ||||||||||||||||||||||||||
19 | ||||||||||||||||||||||||||
20 | ||||||||||||||||||||||||||
21 | ||||||||||||||||||||||||||
22 | ||||||||||||||||||||||||||
23 | ||||||||||||||||||||||||||
24 | ||||||||||||||||||||||||||
25 | ||||||||||||||||||||||||||
26 | ||||||||||||||||||||||||||
27 | ||||||||||||||||||||||||||
28 | ||||||||||||||||||||||||||
29 | ||||||||||||||||||||||||||
30 | ||||||||||||||||||||||||||
31 | ||||||||||||||||||||||||||
32 | ||||||||||||||||||||||||||
33 | ||||||||||||||||||||||||||
34 | ||||||||||||||||||||||||||
35 | ||||||||||||||||||||||||||
36 | ||||||||||||||||||||||||||
37 | ||||||||||||||||||||||||||
38 | ||||||||||||||||||||||||||
39 | ||||||||||||||||||||||||||
40 | ||||||||||||||||||||||||||
41 | ||||||||||||||||||||||||||
42 | ||||||||||||||||||||||||||
43 | ||||||||||||||||||||||||||
44 | ||||||||||||||||||||||||||
45 | ||||||||||||||||||||||||||
46 | ||||||||||||||||||||||||||
47 | ||||||||||||||||||||||||||
48 | ||||||||||||||||||||||||||
49 | ||||||||||||||||||||||||||
50 | ||||||||||||||||||||||||||
51 | ||||||||||||||||||||||||||
52 | ||||||||||||||||||||||||||
53 | ||||||||||||||||||||||||||
54 | ||||||||||||||||||||||||||
55 | ||||||||||||||||||||||||||
56 | ||||||||||||||||||||||||||
57 | ||||||||||||||||||||||||||
58 | ||||||||||||||||||||||||||
59 | ||||||||||||||||||||||||||
60 | ||||||||||||||||||||||||||
61 | ||||||||||||||||||||||||||
62 | ||||||||||||||||||||||||||
63 | ||||||||||||||||||||||||||
64 | ||||||||||||||||||||||||||
65 | ||||||||||||||||||||||||||
66 | ||||||||||||||||||||||||||
67 | ||||||||||||||||||||||||||
68 | ||||||||||||||||||||||||||
69 | ||||||||||||||||||||||||||
70 | ||||||||||||||||||||||||||
71 | ||||||||||||||||||||||||||
72 | ||||||||||||||||||||||||||
73 | ||||||||||||||||||||||||||
74 | ||||||||||||||||||||||||||
75 | ||||||||||||||||||||||||||
76 | ||||||||||||||||||||||||||
77 | ||||||||||||||||||||||||||
78 | ||||||||||||||||||||||||||
79 | ||||||||||||||||||||||||||
80 | ||||||||||||||||||||||||||
81 | ||||||||||||||||||||||||||
82 | ||||||||||||||||||||||||||
83 | ||||||||||||||||||||||||||
84 | ||||||||||||||||||||||||||
85 | ||||||||||||||||||||||||||
86 | ||||||||||||||||||||||||||
87 | ||||||||||||||||||||||||||
88 | ||||||||||||||||||||||||||
89 | ||||||||||||||||||||||||||
90 | ||||||||||||||||||||||||||
91 | ||||||||||||||||||||||||||
92 | ||||||||||||||||||||||||||
93 | ||||||||||||||||||||||||||
94 | ||||||||||||||||||||||||||
95 | ||||||||||||||||||||||||||
96 | ||||||||||||||||||||||||||
97 | ||||||||||||||||||||||||||
98 | ||||||||||||||||||||||||||
99 | ||||||||||||||||||||||||||
100 |