question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Bug] Event JSON is `stringify`'d after being sent via browser Javascript

See original GitHub issue

Package + Version

  • @sentry/browser
  • @sentry/node
  • raven-js
  • raven-node (raven for node)
  • other:

Version:

5.6.1

Description

I’m initializing Sentry in the template of a large, legacy Rails app. I have the following at the top of a common html template:

<script src="https://browser.sentry-cdn.com/5.6.1/bundle.min.js" integrity="<integrity>" crossorigin="anonymous">
</script>
<script>
  Sentry.init({
    dsn: "<%= ENV['SENTRY_DSN'] %>",
    integrations: [new Sentry.Integrations.Breadcrumbs({ console: false })]
  });
</script>

When I throw a test error, I get the following in the Sentry UI:

There were 4 errors encountered while processing this event

breadcrumbs: Discarded invalid value
Reason | expected a list or values object
Value | []

exception.values: Discarded invalid value
Reason | expected an array
Value | [{"type": "TypeError", "value": "<value>", "stacktrace": {"frames": [{"colno": 3, "filename": "<filename>", "function": "<function>", "in_app": true, "lineno": 242}, {"colno": 49, "filename": "<filename>", "function": "<function>", "in_app": true, "lineno": 45}]}}]

sdk.integrations: Discarded invalid value
Reason | expected an array
Value | ["InboundFilters", "FunctionToString", "TryCatch", "GlobalHandlers", "LinkedErrors", "UserAgent", "Breadcrumbs"]

sdk.packages: Discarded invalid value
Reason | expected an array
Value | [{"name": "npm:@sentry/browser", "version": "5.6.1"}]

By logging the event being sent in the beforeSend hook, I’ve confirmed that in the browser, the event data is all valid JSON:

Screen Shot 2019-08-14 at 9 05 37 AM

I suspected that the data was being JSON.stringify’d when being parsed, and confirmed that by intentionally stringify-ing all the data in the beforeSend hook:

Sentry.init({
  dsn: "<%= ENV['SENTRY_DSN'] %>",
  debug: true,
  integrations: [new Sentry.Integrations.Breadcrumbs({ console: false })],
  beforeSend: function(event, hint) {
    event.message = hint.originalException.message;
    event.breadcrumbs = JSON.stringify([]);
    event.exception.values = JSON.stringify(event.exception.values);
    event.sdk.integrations = JSON.stringify(event.sdk.integrations);
    event.sdk.packages = JSON.stringify(event.sdk.packages);

    return event;
  }
});

Here is the result in Sentry (note that it has been JSON.stringify’d twice):

There were 4 errors encountered while processing this event

breadcrumbs: Discarded invalid value
Reason | expected a list or values object
Value | "[]"

exception.values: Discarded invalid value
Reason | expected an array
Value | "[{\"type\": \"TypeError\", \"value\": \"Cannot read property 'environment' of undefined\", \"stacktrace\": {\"frames\": [{\"colno\": 3, \"filename\": \"<filename>\", \"function\": \"<function>\", \"in_app\": true, \"lineno\": 242}, {\"colno\": 49, \"filename\": \"<filename>\", \"function\": \"<function>\", \"in_app\": true, \"lineno\": 45}]}}]"

sdk.integrations: Discarded invalid value
Reason | expected an array
Value | "[\"InboundFilters\", \"FunctionToString\", \"TryCatch\", \"GlobalHandlers\", \"LinkedErrors\", \"UserAgent\", \"Breadcrumbs\"]"

sdk.packages: Discarded invalid value
Reason | expected an array
Value | "[{\"name\": \"npm:@sentry/browser\", \"version\": \"5.6.1\"}]"

I know the browser Javascript use case for Sentry is a little more rare these days. Is it possible that there’s some bug affecting how that data is being processed? I’d appreciate any guidance! Thanks very much.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
eelzoncommented, Aug 21, 2019

I ended up getting to the bottom of this, and it was a fun one (and unrelated to Sentry itself). I’ll explain it here in case an intrepid engineer googling a similar error lands here someday.

Deep in this codebase, which is over a decade old, the Javascript library Prototype.js v1.6.1 was getting included, which adds polyfills for common Javascript helpers that aren’t available in what are now considered very, very old browsers. There is a known bug (https://github.com/prototypejs/prototype/issues/327) that Prototype adds an Array.prototype.toJSON function that gets used automatically when JSON.stringify is called, resulting in the array getting processed twice. (A more detailed explanation of what is happening can be found here: https://stackoverflow.com/a/6611126.)

To fix, the options are upgrading to Prototype.js 1.7.0+, or adding an override for JSON.stringify similar to what is described here: https://stackoverflow.com/a/29778126.

0reactions
kamilogorekcommented, Aug 22, 2019

@eelzon thanks for the write-up!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Is it not possible to stringify an Error using JSON.stringify?
This works fine for a native ExpressJS Error object, but it will not work with a Mongoose error. Mongoose errors have nested objects...
Read more >
JSON.stringify() - JavaScript - MDN Web Docs
The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or ...
Read more >
Beware of Using JSON.stringify() for Logging - Level Up Coding
Recently I was working on a legacy system built on AWS Lambda and Node.js. It uses the console object along with JSON.stringify() to...
Read more >
154136 - JSON.stringify miss stringifying Arrays - Monorail
What is the expected behavior? JSON.stringify(JSON.parse) should result in the same string it started with. What went wrong? Notice that the [ ...
Read more >
How To Use JSON.parse() and JSON.stringify() - DigitalOcean
JSON.parse() takes a JSON string and transforms it into a JavaScript object. ... Trailing commas are not valid in JSON, so JSON.parse() throws...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found