dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.23k stars 1.58k forks source link

JSON chunked decoder throws an exception when closed without any added values #44881

Open jiahaog opened 3 years ago

jiahaog commented 3 years ago

Would have expected the following to be a no-op:

import 'dart:async';
import 'dart:convert';

void main() {
  final controller = StreamController<Object>();
  final sink = json.decoder.startChunkedConversion(controller.sink);

  // Uncommenting these lines makes the error go away.
  // sink.add('{');
  // sink.add('}');

  sink.close();
}

But the following exception is thrown:

Web ``` Uncaught Error: FormatException: SyntaxError: Unexpected end of JSON input ```
VM ``` Unhandled exception: FormatException: Unexpected end of input (at character 1) ^ #0 _ChunkedJsonParser.fail (dart:convert-patch/convert_patch.dart:1404:5) #1 _ChunkedJsonParser.close (dart:convert-patch/convert_patch.dart:522:7) #2 _JsonStringDecoderSink.close (dart:convert-patch/convert_patch.dart:1503:13) #3 _ConverterStreamEventSink.close (dart:convert/chunked_conversion.dart:81:18) #4 _SinkTransformerStreamSubscription._handleDone (dart:async/stream_transformers.dart:132:24) #5 _RootZone.runGuarded (dart:async/zone.dart:1534:10) #6 _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:394:13) #7 _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:404:15) #8 _BufferingStreamSubscription._close (dart:async/stream_impl.dart:291:7) #9 _SyncStreamControllerDispatch._sendDone (dart:async/stream_controller.dart:741:19) #10 _StreamController._closeUnchecked (dart:async/stream_controller.dart:596:7) #11 _StreamController.close (dart:async/stream_controller.dart:589:5) #12 _StreamTransformerWrapperSink.close (package:async/src/stream_sink_transformer/stream_transformer_wrapper.dart:62:17) #13 DelegatingStreamSink.close (package:async/src/delegate/stream_sink.dart:47:27) #14 _CloseGuaranteeSink.close (package:stream_channel/src/close_guarantee_channel.dart:81:22) #15 Stream.pipe. (dart:async/stream.dart:698:70) ```

https://dart-review.googlesource.com/c/sdk/+/183540 should help to fix this, but I'm not sure if it's the right fix. Please advise if otherwise 🙂

SDK version: 11106861049846b9b9ddc524d3da9a975d91d66a

lrhn commented 3 years ago

The JSON decoder expects to see precisely one JSON value. Seeing zero is an error, so that's working as intended. It would be nice-to-have if the decoder could also parse multiple (or zero) concatenated JSON values. Possibly only in the chunked conversion case, because then we can call the sink multiple times and not have to worry about returning more than one value. That's occasionally useful. It's currently not possible

I'll keep this issue as an enhancement request for allowing that.