grpc / grpc-dart

The Dart language implementation of gRPC.
https://pub.dev/packages/grpc
Apache License 2.0
861 stars 271 forks source link

Init model from JSON error with message: "Invalid radix-10 number" #470

Closed gl-ihorkoblan closed 3 years ago

gl-ihorkoblan commented 3 years ago

I have json string of an GRPC model. And try to fulfil GRPC model from json like:

try {
    final String info = await _methodChannel.invokeMethod(GRPCMethod.getDeviceInformation); // Getting json from native grpc model
      var response = GetDeviceInformationResponse.fromJson(info);
      return response;
    } catch (e) {
// Getting error: "Invalid radix-10 number"
      return GetDeviceInformationResponse.create();
    }

Please help how to fix it?

gl-ihorkoblan commented 3 years ago

Just copied source code of how it works: https://github.com/dart-lang/protobuf/blob/master/protobuf/lib/src/protobuf/json.dart#L80

void _mergeFromJsonMap(_FieldSet fs, Map<String, dynamic> json, ExtensionRegistry registry) {
  var keys = json.keys;
  var meta = fs._meta;
  for (var key in keys) {
    var fi = meta.byTagAsString[key];
    if (fi == null) {
      if (registry == null) continue; // Unknown tag; skip
      fi = registry.getExtension(fs._messageName, int.parse(key));// THE BUG IS HERE  **int.parse(key)**
      if (fi == null) continue; // Unknown tag; skip
    }
    if (fi.isMapField) {
      _appendJsonMap(fs, json[key], fi, registry);
    } else if (fi.isRepeated) {
      _appendJsonList(fs, json[key], fi, registry);
    } else {
      _setJsonField(fs, json[key], fi, registry);
    }
  }
}

As you can see the reason of the bug is in this line: fi = registry.getExtension(fs._messageName, int.parse(key));

Because it tries to parse key into int, but the reason is that key is not int. key is String. It cause a bug "Invalid radix-10 number"

So please help. Maybe I'm doing something wrong? Or it's a bug of grpc?

mraleph commented 3 years ago

There are two different JSON encodings for protobuf's: jspb (compact and tag based) and Proto3 JSON (name based). Message.fromJson expects JSPB and your message is most likely Proto3 JSON, judging by the error. To unpack that you need to do GetDeviceInformationResponse.create()..mergeFromProto3Json(jsonDecode(info)). Please refer to documentation for further information.

Also please don't use issue tracker as a help forum - use StackOverflow for that.