getsentry / sentry-javascript

Official Sentry SDKs for JavaScript
https://sentry.io
MIT License
7.97k stars 1.57k forks source link

Sentry client is unable to show proper information for brotli compressed files #2065

Closed kirananto closed 4 years ago

kirananto commented 5 years ago

Package + Version

Version:

5.1.1

Description

Since our website sends Brotli compressed data to the browser. sentry is unable to process the information in order to provide proper stack trace or code environment, which makes it harder to debug and get any valid information from sentry.

[Y�Q¶i�
,�����X�xl'��V�f�aL�� tp#V^���199,���
N�YB����ik��D�Z�HC])���Zw�����[U�GON܀���һ�9��"x;!��X����z�0��b��E�6���
��,�}��
�]�j�Ƿ/���ǡ]�_�ʱ95���'߫_���]�]P"3�&��m%���.�g�L����4*!���ׯ�f��" No9��W�6>�GݛHƊ9��qb gS�eB��@����i}�'�D��fk'��W����Vl7��MM�I�]n {snip}
X

This is what we see in the exceptions tab.

kamilogorek commented 5 years ago

You'd need to write an event processor to handle this.

Sentry.configureScope(scope => {
  scope.addEventProcessor((event, hint) => {
    // here hint should contain your raw data which can be decompressed and used
    return event;
  })
})

Can you provide a repro case for it?

kirananto commented 5 years ago

Yes it happens for all bugs on our project as we serve only brotli files.. as our dashboard is supported only on chrome v57 and above (which supports brotli compression)

I tried to get data from the hint that we get in addEventProcessor. But can't decompress the brotli file unless we have the entire file. it just throws errors.

marcins commented 4 years ago

We also ran into this issue, however the root cause was due to the particular way our serving infrastructure is setup. I found a workaround for our case, so I'll document it here in case it helps others.

In our environment we have Sentry download the sourcemaps from production (as opposed to uploading them as part of release), this is for historical reasons, but it's material to this.

We serve our gzip'd assets from /assets/foo.HASH.js and our Brotli compressed assets from /assets-brotli/foo.HASH.js. Sourcemaps are uploaded to both folders, but always contain gzip'd sourcemaps.

When we generate our HTML pages we use server-side logic to read the Accept-encoding header and either produce references to the Brotli or Gzip'd assets on our CDN depending on the result. Our CDN serves JS assets in /assets with a Content-encoding: gzip and /assets-brotli with Content-encoding: br.

Now, when a new error occurs within code served as Brotli, when the error reaches Sentry it will first try and download the asset from our CDN. It downloads it using the original asset path in the stack trace - that is /assets-brotli/foo.HASH.js. However, Sentry sends an Accept-encoding: gzip header with this request. Our CDN doesn't do any parsing of this header at this point, and so will serve /assets-brotli/foo.HASH.js with a forced Content-encoding: br header and Brotli content. Sentry doesn't deal with the encoding, so you see the broken context like above. In addition Sentry can't read the Sourcemap link at the bottom of the asset, so no sourcemapping occurs.

So, my workaround, in the beforeSend method we massage the stacktrace filename attributes (in exception.values[].stacktrace.frames[].filename) to replace /assets-brotli/ with /assets/. These assets are the same in terms of content and filename, just the compression differs. This means when Sentry requests the original asset it gets the GZIPd one and everything works fine from there.

YMMV, this worked for our particular situation. I guess we also could solve this by uploading assets and sourcemaps to Sentry as part of the release process, this would avoid Sentry needing to retrieve the assets from our CDN. This isn't as quick a fix for our particular case as the one above though. This also wouldn't happen if our CDN contained a single assets folder and used headers to serve the appropriate encoding.

For your case @kirananto, you could consider either uploading your assets to Sentry using the Sentry CLI as part of your build, or you could also produce GZIP'd assets just for Sentry.

I guess for the Sentry side, @kamilogorek, you would need to use a HTTP request library that supports Brotli compression to fix the use case where only Brotli assets are available.

rpemberton commented 4 years ago

We have this issue as well. @kamilogorek are you able to help me find where and how support for brotli could be added?

For example, is this the correct place? https://github.com/getsentry/sentry/blob/612c79cd5acef2e86e4df649902739afadc4497f/src/sentry/middleware/proxy.py#L161

mitsuhiko commented 4 years ago

So the issue here is that the server side fetching code does not support brotli. The workaround for now is to upload release artifacts instead.

pesektomas commented 2 years ago

Hi @kirananto,

could you please share the solution? It is not clear to me from the above where the problem was.

I understand what @marcins is writing, but it seems crazy to me and I hope there is a simpler option.

Thx

pesektomas commented 2 years ago

Okay, I get it. I had to upload the uncompressed files to sentry and it works now.

Sorry for the false alarm.