JsCommunity/json-rpc-protocol

Unable to properly parse requests created by `format`

Closed this issue · 5 comments

Example:

const protocol = require('json-rpc-protocol');

(function () {
  'use strict';

  let message = protocol.format.request(
    Number(new Date()),
    'example',
    []);

  protocol.parse(JSON.stringify(message));
}());

Outputs the following:

InvalidRequest: invalid identifier: undefined instead of number or string
    at checkId (/Volumes/Macintosh HD 2/Projects/PlayNetwork/music-nodejs/node_modules/json-rpc-protocol/dist/parse.js:1:1654)
    at Object.parse (/Volumes/Macintosh HD 2/Projects/PlayNetwork/music-nodejs/node_modules/json-rpc-protocol/dist/parse.js:1:3292)
    at /Volumes/Macintosh HD 2/Projects/PlayNetwork/music-nodejs/test/sandbox/json-rpc.js:11:11
    at Object.<anonymous> (/Volumes/Macintosh HD 2/Projects/PlayNetwork/music-nodejs/test/sandbox/json-rpc.js:12:2)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)

Testing more - found that parse only fails when parsing a JSON string - not when attempting to parse the actual object.

Ok - after further debugging and testing, I've found the following:

Refer to this line: https://github.com/JsCommunity/json-rpc-protocol/blob/master/src/parse.js#L112

Currently reads as:

message = JSON.parse(message)

Changing it to the following actually works:

message = JSON.parse(JSON.parse(message))

This is pretty ugly... not sure why the first JSON.parse seemingly has no effect.

It's because all format functions return JSON strings, not objects, therefore you should not stringify them a second time.

// This works.
protocol.parse(protocol.format.request(
  Date.now(),
  'example',
  []
))

If you need the raw objects you have to parse them first:

const requestObject = JSON.parse(protocol.format.request(
  Date.now(),
  'example',
  []
))

It may be surprising first but the format functions returns actual JSON-RPC messages, which are, of course, JSON encoded.

Ah, thank you for the clarity on this. Great module, btw - thank you for publishing it!

Your welcome :)