diff --git a/CHANGELOG.md b/CHANGELOG.md index c7f1652e687c0..f27cacb64cc24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.3-dev (unreleased) + +* Accept responses even if the server converts the ID to a String. + ## 2.2.2 * Fix `Peer.close()` throwing `Bad state: Future already completed`. diff --git a/lib/src/client.dart b/lib/src/client.dart index 33a529c6ea994..d89a6237436e9 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -197,7 +197,9 @@ class Client { /// resolved. void _handleSingleResponse(response) { if (!_isResponseValid(response)) return; - var request = _pendingRequests.remove(response['id']); + var id = response['id']; + id = (id is String) ? int.parse(id) : id; + var request = _pendingRequests.remove(id); if (response.containsKey('result')) { request.completer.complete(response['result']); } else { @@ -212,7 +214,9 @@ class Client { bool _isResponseValid(response) { if (response is! Map) return false; if (response['jsonrpc'] != '2.0') return false; - if (!_pendingRequests.containsKey(response['id'])) return false; + var id = response['id']; + id = (id is String) ? int.parse(id) : id; + if (!_pendingRequests.containsKey(id)) return false; if (response.containsKey('result')) return true; if (!response.containsKey('error')) return false; diff --git a/test/client/client_test.dart b/test/client/client_test.dart index c1edbe4c7da22..228acbda128c6 100644 --- a/test/client/client_test.dart +++ b/test/client/client_test.dart @@ -31,6 +31,27 @@ void main() { completion(equals('bar'))); }); + test('sends a message and returns the response with String id', () { + controller.expectRequest((request) { + expect( + request, + allOf([ + containsPair('jsonrpc', '2.0'), + containsPair('method', 'foo'), + containsPair('params', {'param': 'value'}) + ])); + + return { + 'jsonrpc': '2.0', + 'result': 'bar', + 'id': request['id'].toString() + }; + }); + + expect(controller.client.sendRequest('foo', {'param': 'value'}), + completion(equals('bar'))); + }); + test('sends a notification and expects no response', () { controller.expectRequest((request) { expect(