fingerprintjs-pro-server-api-node-sdk icon indicating copy to clipboard operation
fingerprintjs-pro-server-api-node-sdk copied to clipboard

SDK Fails with "SdkError: Failed to parse JSON response" on non-200 responses

Open ohana54 opened this issue 4 months ago • 10 comments

Hi,

We noticed that sometimes the service returns 500/502 errors and the response body is html. The code doesn't check the status code and tries to parse the body as json, which fails with the error "SdkError: Failed to parse JSON response".

Context: https://github.com/fingerprintjs/fingerprintjs-pro-server-api-node-sdk/blob/0feaf6bfee8a9355ddd0b06feffb35e81238fe88/src/serverApiClient.ts#L86-L91

It would be nice to handle these cases so we can get a meaningful and correct error back. I'll be happy to submit a PR if needed.

Thanks!

ohana54 avatar Aug 05 '25 10:08 ohana54

Hi @ohana54! Thanks for reaching out to us, we will look into it and get back to you.

necipallef avatar Aug 07 '25 08:08 necipallef

Hi again @ohana54!

We acknowledge the need for improved error handling on the SDK side. However, we have been unable to reproduce the issue you are experiencing. A potential fix is already in progress, but to ensure we address the problem effectively, we would appreciate more details. Could you please provide reproducible steps? Or is this one of those cases where the issue cannot be reproduced reliably?

necipallef avatar Aug 11 '25 14:08 necipallef

Hi, how did you try to reproduce? It should be reproducible by returning a fake html response which will cause the json parsing function to fail.

ohana54 avatar Aug 11 '25 15:08 ohana54

Hi @ohana54!

Returning a mocked HTML response is indeed how we usually write tests for our implementation, and we plan to do so here as well. However, this will not resolve the other issue you mentioned — you will still encounter HTTP 500/502 errors with HTML content, and I am also interested in preventing those. I’ve spoken with our platform team, and they were unable to find any logs of these errors on their side.

We do plan to improve the SDK’s error handling, but could it be possible that these errors originate from unrelated parts of your code? If you are certain they are coming from the Fingerprint SDK and Fingerprint endpoints, could you share more details so we can investigate and work on a fix? What I mean is a solution that would stop HTTP 500/502 errors from occurring.

necipallef avatar Aug 13 '25 07:08 necipallef

Hi,

Here's an example log of what we got. This is the response object:

{
    status: 502,
    statusText: 'Bad Gateway',
    headers: Headers {
      server: 'awselb/2.0',
      date: 'Tue, 12 Aug 2025 07:35:34 GMT',
      'content-type': 'text/html',
      'content-length': '122',
      connection: 'keep-alive'
    },
    body: ReadableStream { locked: false, state: 'readable', supportsBYOB: true },
    bodyUsed: false,
    ok: false,
    redirected: false,
    type: 'basic',
    url: 'https://api.fpjs.io/events/1754984133971.bpd8qO?ii=fingerprint-pro-server-node-sdk%2F6.1.0'
 }

As we can see it originates from a call to your server. Maybe it hit something else on the way, I can't really tell.

The stack trace for the actual error we get:

SyntaxError: Unexpected token '<', \"<html>
  <h\"... is not valid JSON
      at JSON.parse (<anonymous>)
      at parseJSONFromBytes (node:internal/deps/undici/undici:6227:19)
      at successSteps (node:internal/deps/undici/undici:6208:27)
      at readAllBytes (node:internal/deps/undici/undici:5165:13)
      at process.processTicksAndRejections 

According to the stack trace, the response body is html.

you will still encounter HTTP 500/502 errors with HTML content

I might be missing something, what do you mean by that? When you call fetch, you take the response and try to parse it as JSON, without checking the response status code. So even if the status code is 502 (like we can see in the log above) you still try to parse the response. Again, unless I'm missing something.

Thank you for trying to get to the bottom of it, I completely understand the need to understand it and not fix it "blindly".

ohana54 avatar Aug 13 '25 07:08 ohana54

The response object you shared is very helpful, thank you! Initial investigation showed that we cannot find this request reaching our servers, but having awselb in the server header shows that it is returned by AWS Elastic Load Balancer, a service that we use. We started a deeper investigation for this and will let you know as soon as something turns up.

necipallef avatar Aug 13 '25 17:08 necipallef

Also, could you please share below:

  • the HTML content that's returned from AWS
  • how often does this happen, does it always happen with some particular events, such as 1754984133971.bpd8qO
  • a few other example responses, so that we can see if we can track them down, or find something in common

Answering these will help us debug faster. Thanks a lot!

necipallef avatar Aug 13 '25 17:08 necipallef

Hi,

I don't have the html as the response is internal in the sdk and it fails at that point. It doesn't happen often, and honestly it's understood that sometimes there are network issues or momentary errors, it would just be helpful when that happens to return some error we can catch and handle accordingly.

ohana54 avatar Aug 14 '25 07:08 ohana54

Actually, I now see that the SdkError you throw has the response in it. It means I can check the response status code and react accordingly (basically ignoring the underlying syntax error thrown from the json parsing).

In that case, my original issue can be solved without any changes on your side.

ohana54 avatar Aug 14 '25 08:08 ohana54

The SdkError is designed to enable users to recover the original response in any case, so that should be a good enough workaround as you mentioned.

We will introduce better error handling and I'll let here know when it is ready to use.

In the meantime, if you come across this problem again and could share the original response body that AWS returns, that will be appreciated.

Thanks!

necipallef avatar Aug 14 '25 13:08 necipallef