0

I've looked around for a suitable method to catch or prevent invalid JSON.parse calls, specifically in the case of WebSocket messages that don't involve type/catch block due to its performance hit.

I've almost fully moved my RESTful API to pure WebSocket API using JSON for communications. The only problem is, I can't figure out how to prevent JSON.parse from halting the app when a malformed message string is put through my onmessage function. All messages sent from the server are theoretically proper JSON that's been stringified, so the question also is, is this an edge case to worry about? Since the function thats used to send data from the serverside JSON stringifies before sending.

I'm using React and Redux with redux-thunk to open a WebSocket and add event listeners, so on a message the function below is being run.

function onMessage(msg) {
  const data = JSON.parse(msg.data);
  return {
    type: data.type,
    data: data.data
  }
}

But this, of course, breaks if msg is not a valid JSON string then halting execution of the app.

So, without a try/catch block, is the only option to (somehow) ensure valid JSON is being sent? Or is this an edge case I shouldn't be worried about.


EDIT

This may not be such a big issue for client side since all messages are coming from a centralized point (the server), though on the other hand, quite a big issue for the server, seeing it's possible it to receive messages that have not been sent from the application.

Is try/catch really the devil it's made out to be? Since the only thing I can think of is to create a regex check, which in itself would end up becoming quite complicated.

sparcut
  • 795
  • 1
  • 10
  • 27
  • Why would server not send valid `JSON`? – guest271314 Aug 09 '17 at 03:37
  • @guest271314 Yeah, after thinking about it, it's probably not so much an issue for the client, though more so an issue for the server since it's possible for a non-JSON message to be sent, in which case causing the error on the server. – sparcut Aug 09 '17 at 03:44
  • Why would it be possible for invalid `JSON` to be sent to server? – guest271314 Aug 09 '17 at 03:45
  • @guest271314 Since WebSocket messages are strings, there is no enforcement to send `JSON`. Thus, one could send any string, which would then be run through `JSON.parse` causing the said error to be thrown. The client app will never send non-JSON or malformed `JSON` but it is very simple for one to send a non-JSON message to the WebSocket server thus crashing it with this error. – sparcut Aug 09 '17 at 05:58
  • @guest271314 Added extra info to initial post. – sparcut Aug 09 '17 at 06:11

1 Answers1

4

don't involve type/catch block due to its performance hit.

Forget the myths. You want to catch an exception, like the one from JSON.parse, you use a try/catch block. It's that simple and not a significant performance hit. Of course you could also write your own logic to validate JSON strings (not with regex!), but that's gonna be a complete parser which just doesn't use exceptions to signal malformed input - and much slower than the native function.

Is this an edge case to worry about?

On the client, hardly. You're controlling the server and making sure to send only valid JSON strings. If you don't, I'd worry much more about the server than about a few clients crashing. The users will most likely reload the page and continue.

Though on the other hand, quite a big issue for the server, seeing it's possible it to receive messages that have not been sent from the application.

Yes. On the server you absolutely need to worry about malformed input. If sending invalid JSON makes your server crash, that's really bad.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • on the server side, aren't there JSON libraries that return an error object instead of throwing an exception? thereby reducing the performance cost related to `longjmp` instructions? – Myst Aug 09 '17 at 06:57
  • @Myst There might be, I don't know, but I doubt they would have any advantage. Switching on the return type is hardly different from a `longjmp`, and remember that JavaScript is not C++. [The performance "cost" of `try` is absolutely negligible](https://stackoverflow.com/q/19727905/1048572). Parsing client messages is not performance-critical code like a tight loop. The parser itself will cost magnitudes more than the `try` block overhead. – Bergi Aug 09 '17 at 07:06
  • thanks for pointing it out. I guess my brain is wired for C (and C++) and I tend to forget the up-sides of interpreted languages (as opposed to the down-sides, which I am morbidly and constantly aware of). – Myst Aug 09 '17 at 07:15
  • 1
    @Bergi Cheers for that advice, looking at performance of `try`/`catch`, and `try`/`catch` with `JSON.parse` compared to running by itself, there is little to no performance hit. After some additional digging, it seems **this** is the proper use for the `try`/`catch`, [as per question on software engineering exchange.](https://softwareengineering.stackexchange.com/a/144328) – sparcut Aug 09 '17 at 07:17
  • 2
    @sparcut Nice find, I especially like [this answer](https://softwareengineering.stackexchange.com/a/241039/66652) – Bergi Aug 09 '17 at 08:08