13

Solution to SignalR error 'Unexpected token in JSON' when parsing event data

 3 years ago
source link: https://blog.jongallant.com/2021/09/signalr-unexpected-token-in-json/?utm_campaign=Feed%3A+jongallant+%28Jon+Gallant%29
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Solution to SignalR error 'Unexpected token in JSON' when parsing event data

I’ve been writing some UI automation tests with Playwright and was trying to parse a SignalR event. Like so:

const imageEvent = JSON.parse(event.payload.toString()) as ImageEvent;

And I got this error:

  1) tests/memealyzer.spec.ts:15:1 › Add Meme Test =================================================

    webSocket.waitForEvent: Unexpected token  in JSON at position 658

      49 |   expect(afterCardCount).toEqual(beforeCardCount + 1);
      50 |
    > 51 |   await webSocket.waitForEvent("framereceived", (event) => {
         |                   ^
      52 |     if (event.payload.indexOf("ReceiveImage") > 0) {
      53 |       const imageEvent = JSON.parse(event.payload.toString()) as ImageEvent;

As you can see from this screenshot:
ScreenshotScreenshot

It looks like a christmas tree is in my JSON. I assumed it was an invalid char added by my code or playwright’s code, etc.

Here’s what it looks like in the debugger:
DebuggerDebugger

So, I removed it like so:

const payload = event.payload.toString().replace("", ""); // Remove hidden char

ReplaceReplace

Little did I know that character is a record separator! After I tweeted my code, David Fowler pointed me to this:

You want to split based on that character instead of removing it. A single websocket payload can contain multiple messages https://t.co/3sHUdjCpoB

— David Fowler 🇧🇧💉💉 (@davidfowl) September 1, 2021

Here’s the code that SignalR uses to parse and iterate through the results:
https://github.com/dotnet/aspnetcore/blob/e18394c8a933a5e03c0f5e4d614b622c2cb0a4b7/src/SignalR/clients/ts/signalr/src/TextMessageFormat.ts#L6-L22

So, instead of removing the char, I now split on it and loop through the results.

  await webSocket.waitForEvent("framereceived", (event) => {
    if (event.payload.indexOf("ReceiveImage") > 0) {
      const imageEvents = TextMessageFormat.parse(event.payload.toString());
      for (let imageEventRaw of imageEvents) {
        const imageEvent = JSON.parse(imageEventRaw) as ImageEvent;
        actualId = imageEvent.arguments[0].Id;
        return true;
      }
    }
  });

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK