# Troubleshooting | Sentry for Astro

The SDK is not sending any data

If you set up the Sentry SDK and it's not sending any data to Sentry:

* Check that you have configured a DSN and that you are passing it to the `dsn` option in `Sentry.init()`.

  If you are using environment variables to pass the DSN, make sure the environment variables are set in all relevant environments. Additionally, if you are using environment variables inside a framework, check that the framework will include the environment variables in your bundle. Often this means you will have to prefix your environment variables with special prefixes defined by your framework (`NEXT_PUBLIC_` in Next.js, `NUXT_` in Nuxt, `VITE_` for Vite projects, `REACT_APP_` for Create React App, ...).

* Check that you have disabled any ad-blockers.

* Set `debug: true` in the `Sentry.init()` options and observe your console output when you start your application. The SDK may tell you why it is not sending any data.

* Check the [Stats](https://sentry.io/orgredirect/organizations/:orgslug/stats/) and [Suscription](https://sentry.io/orgredirect/organizations/:orgslug/settings/billing/overview/) pages in Sentry. You may have ran out of quota.

Updating to a new Sentry SDK version

If you update your Sentry SDK to a new major version, you might encounter breaking changes that need some adaption on your end. Check out our [migration guide](https://github.com/getsentry/sentry-javascript/blob/master/MIGRATION.md) to learn everything you need to know to get up and running again with the latest Sentry features.

Debugging additional data

You can view the JSON payload of an event to see how Sentry stores additional data in the event. The shape of the data may not exactly match the description.

[![Red box highlighting where to find the JSON connected to an event](https://docs.sentry.io/_next/image/?url=%2Fmdx-images%2Fevent_JSON-7MDJIX3K.png%231716x319\&w=3840\&q=75)](https://docs.sentry.io/mdx-images/event_JSON-7MDJIX3K.png)

For more details, see the [full documentation on Event Payload](https://develop.sentry.dev/sdk/data-model/event-payloads/).

Max JSON payload size

`maxValueLength` has a default value of 250, but you can adjust this value according to your needs if your messages are longer. Please note that not every single value is affected by this option.

CORS attributes and headers

To gain visibility into a JavaScript exception thrown from scripts originating from different origins, do two things:

1. Add a crossorigin=”anonymous” script attribute

```bash
 <script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>
```

The script attribute tells the browser to fetch the target file “anonymously.” Potentially user-identifying information like cookies or HTTP credentials won’t be transmitted by the browser to the server when requesting this file.

2. Add a Cross-Origin HTTP header

```bash
Access-Control-Allow-Origin: *
```

Cross-Origin Resource Sharing (CORS) is a set of APIs (mostly HTTP headers) that dictate how files ought to be downloaded and served across origins.

By setting `Access-Control-Allow-Origin: *`, the server is indicating to browsers that any origin can fetch this file. Alternatively, you can restrict it to a known origin you control:

```bash
 Access-Control-Allow-Origin: https://www.example.com
```

Most community CDNs properly set an `Access-Control-Allow-Origin` header.

```bash
 $ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | \
 grep -i "access-control-allow-origin"

 Access-Control-Allow-Origin: *
```

Unexpected OPTIONS request

If your application started to misbehave because of performing additional OPTIONS requests, it is most likely an issue with unwanted `sentry-trace` request headers, which can happen when you are using too generic a configuration for our Tracing Integration in the Browser SDK.

To fix this, change the `tracePropagationTargets` option during SDK initialization. For more details, see [Automatic Instrumentation](https://docs.sentry.io/platforms/javascript/guides/astro/tracing/instrumentation/automatic-instrumentation.md#tracePropagationTarget) in our Tracing documentation.

\`instrument.js\` Line Numbers for Console Log statements

If `instrument.js` displays in your console while debugging, add Sentry to your [Framework Ignore List](https://developer.chrome.com/docs/devtools/settings/ignore-list/#skip-extensions) by adding this pattern: `/@sentry/`

Chrome then ignores the SDK stack frames when debugging.

Dealing with Ad-Blockers

When you are using our CDN, ad-blocking or script-blocking extensions may prevent our SDK from being fetched and initialized properly. Because of this, any call to the SDKs API will fail and may cause your application to behave unexpectedly.

Additionally, even when the SDK is downloaded and initialized correctly, Sentry endpoints that need to receive captured data may be blocked as well. This prevents any error reports, sessions health, or performance data from being delivered, making it effectively unavailable in [sentry.io](https://sentry.io).

Furthermore, some browsers, like [Brave](https://brave.com/), have built-in ad-blockers that may block requests sent to our endpoint. Even if users deactivate your domain from blocking, Brave might continue to block [requests made from service workers](https://github.com/getsentry/sentry/issues/47912#issuecomment-1573714875).

You can work around our CDN bundles being blocked by [using our NPM packages](https://docs.sentry.io/platforms/javascript/guides/astro/troubleshooting.md#using-the-npm-package) and bundling our SDK with your app. However, the endpoint blockage can only be resolved by using a tunnel as explained below.

Using the \`tunnel\` Option

A tunnel is an HTTP endpoint that acts as a proxy between Sentry and your application. Because you control this server, there is no risk of any requests sent to it being blocked. When the endpoint lives under the same origin (although it does not have to in order for the tunnel to work), the browser will not treat any requests to the endpoint as a third-party request. As a result, these requests will have different security measures applied which, by default, don't trigger ad-blockers. A quick summary of the flow can be found below.

[![Tunnel Flow](https://docs.sentry.io/_next/image/?url=%2Fmdx-images%2Ftunnel-7ZZLHFR5.png%231374x1078\&w=3840\&q=75)](https://docs.sentry.io/mdx-images/tunnel-7ZZLHFR5.png)

Starting with version `6.7.0` of the JavaScript SDK, you can use the `tunnel` option to tell the SDK to deliver events to the configured URL, instead of using the DSN. This allows the SDK to remove `sentry_key` from the query parameters, which is one of the main reasons ad-blockers prevent sending events in the first place. This option also stops the SDK from sending preflight requests, which was one of the requirements that necessitated sending the `sentry_key` in the query parameters.

To enable the `tunnel` option, provide either a relative or an absolute URL in your `Sentry.init` call. When you use a relative URL, it's relative to the current origin, and this is the form that we recommend. Using a relative URL will not trigger a preflight CORS request, so no events will be blocked, because the ad-blocker will not treat these events as third-party requests. When using tunneling with server-side SDKs like `@sentry/node` or `@sentry/bun` you must provide an absolute URL.

```javascript
Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
  tunnel: "/tunnel",
});
```

Once configured, all events will be sent to the `/tunnel` endpoint. This solution, however, requires an additional configuration on the server, as the events now need to be parsed and redirected to Sentry. Here's an example for your server component:

```csharp

// This functionality is now built-in to the Sentry.AspNetCore package.
// See https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/#tunnel
// docs for more information.

// This example shows how you could implement it yourself:

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

// Change host appropriately if you run your own Sentry instance.
const string host = "sentry.io";
// Set knownProjectIds to a list with your Sentry project IDs which you
// want to accept through this proxy.
var knownProjectIds = new HashSet<string>() {  };

var client = new HttpClient();
WebHost.CreateDefaultBuilder(args).Configure(a =>
    a.Run(async context =>
    {
        context.Request.EnableBuffering();
        using var reader = new StreamReader(context.Request.Body);
        var header = await reader.ReadLineAsync();
        var headerJson = JsonSerializer.Deserialize<Dictionary<string, object>>(header);
        if (headerJson.TryGetValue("dsn", out var dsnString)
            && Uri.TryCreate(dsnString.ToString(), UriKind.Absolute, out var dsn))
        {
            var projectId = dsn.AbsolutePath.Trim('/');
            if (knownProjectIds.Contains(projectId) && string.Equals(dsn.Host, host, StringComparison.OrdinalIgnoreCase)) {
              context.Request.Body.Position = 0;
              await client.PostAsync($"https://{dsn.Host}/api/{projectId}/envelope/",
                  new StreamContent(context.Request.Body));
            }
        }
    })).Build().Run();
```

If your use-case is related to the SDK package itself being blocked, any of the following solutions will help you resolve this issue.

### [Using the NPM Package](https://docs.sentry.io/platforms/javascript/guides/astro/troubleshooting.md#using-the-npm-package)

The best way to deal with script-blocking extensions is to use the SDK package directly through the `npm` and bundle it with your application. This way, you can be sure that the code will be always be there as you expect it to be.

### [Self-hosting CDN bundles](https://docs.sentry.io/platforms/javascript/guides/astro/troubleshooting.md#self-hosting-cdn-bundles)

The second way is to download the SDK from our CDN and host it yourself. This way, the SDK will still be separated from the rest of your code, but you'll be certain that it won't be blocked since its origin will be the same as the origin of your website.

You can easily fetch it using `curl` or any other similar tool:

```bash
curl https://browser.sentry-cdn.com/5.20.1/bundle.min.js -o sentry.browser.5.20.1.min.js -s
```

### [Using the JavaScript Proxy API](https://docs.sentry.io/platforms/javascript/guides/astro/troubleshooting.md#using-the-javascript-proxy-api)

The last option is to use `Proxy` guard, which will make sure that your code won't break, even when you call our SDK, which was blocked. `Proxy` is supported by all browser except Internet Explorer, though there are no extensions in this browser. Also if `Proxy` is not in any of your user's browser, it will be silently skipped, so you don't have to worry about it breaking anything.

Place this snippet immediately **above** the `<Expandable>` tag containing our CDN bundle. The snippet in a readable format presents like this:

```javascript
if ("Proxy" in window) {
  var handler = {
    get: function (_, key) {
      return new Proxy(function (cb) {
        if (key === "flush" || key === "close") return Promise.resolve();
        if (typeof cb === "function") return cb(window.Sentry);
        return window.Sentry;
      }, handler);
    },
  };
  window.Sentry = new Proxy({}, handler);
}
```

If you would like to copy and paste the snippet directly, here it is minified:

```html
<script>
  if ("Proxy" in window) {
    var n = {
      get: function (o, e) {
        return new Proxy(function (n) {
          return "flush" === e || "close" === e
            ? Promise.resolve()
            : "function" == typeof n
              ? n(window.Sentry)
              : window.Sentry;
        }, n);
      },
    };
    window.Sentry = new Proxy({}, n);
  }
</script>
```

Third party promise libraries

When you include and configure Sentry, our JavaScript SDK automatically attaches global handlers to *capture* uncaught exceptions and unhandled promise rejections. You can disable this default behavior by changing the `onunhandledrejection` option to `false` in your GlobalHandlers integration and manually hook into each event handler, then call `Sentry.captureException` or `Sentry.captureMessage` directly.

You may also need to manage your configuration if you are using a third-party library to implement promises. Also, remember that browsers often implement security measures that can block error reporting when serving script files from different origins.

Events with 'Non-Error Exception'

If you’re seeing errors with the message “Non-Error exception (or promise rejection) captured with keys: x, y, z.”, this happens when you a) call `Sentry.captureException()` with a plain object, b) throw a plain object, or c) reject a promise with a plain object.

You can see the contents of the non-Error object in question in the `__serialized__` entry of the “Additional Data” section.

To get better insight into these error events, we recommend finding where the plain object is being passed or thrown to Sentry based on the contents of the `__serialized__` data, and then turning the plain object into an Error object.

Capturing resource 404s

By default, Sentry does not capture errors when a resource (like an image or a css file) fails to load. If you would like it to do so, you can use the following code. (Note: We recommend loading Sentry as early as possible in any case, but this method in particular will only work if Sentry is loaded before other resources.)

```javascript
document.body.addEventListener(
  "error",
  (event) => {
    if (!event.target) return;

    if (event.target.tagName === "IMG") {
      Sentry.captureException(
        new Error(`Failed to load image: ${event.target.src}`),
      );
    } else if (event.target.tagName === "LINK") {
      Sentry.captureException(
        new Error(`Failed to load css: ${event.target.href}`),
      );
    }
  },
  true, // useCapture - necessary for resource loading errors
);
```

Remember to pass in `true` as the second parameter to `addEventListener()`. Without it, the event handler won't be called, since it's being added to the event target's ancestor rather than the event target itself, and unlike JavaScript runtime errors, `error` events resulting from load failures don't bubble, and therefore must be captured during the `capture` phase. For more information, see [the W3C spec](https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-phases).

SDK causes double invocations of \`addEventListener\` (e.g. duplicated click events)

In very rare cases, the SDK can cause callbacks added via `addEventListener` to an event target (such as a button) to be invoked twice. This is usually a sign of the SDK being intialized too late in the lifecycle of the page. If you can, try initializing the SDK earlier in your application.

If this is not possible or doesn't apply to your use case, set the `unregisterOriginalCallbacks` option in the [`browserApiErrors` integration](https://docs.sentry.io/platforms/javascript/guides/astro/configuration/integrations/browserapierrors.md) to `true`.

Build errors with vite

If you're using the [Vite Bundler](https://vitejs.dev/) and a Sentry NPM package, and you see the following error:

```bash
Error: Could not resolve './{}.js' from node_modules/@sentry/utils/esm/index.js
```

This might be because the [`define`](https://vitejs.dev/config/shared-options.html#define) option in your Vite config is string-replacing some variable used by the Sentry SDK, like `global`, which causes build errors. Vite recommends using `define` for CONSTANTS only, and not putting `process` or `global` into the options. To fix this build error, remove or update your `define` option, as shown below:

`vite.config.ts`

```javascript
export default defineConfig({
   build: {
     sourcemap: true
   },
-  define: {
-    global: {}
-  },
   plugins: [react()]
})
```

Missing module \`diagnostics\_channel\`

If you're getting build errors when using any of the JavaScript SDKs mentioning something along the lines of "Cannot find module diagnostics\_channel", try to configure your build tool to either externalize or ignore the `diagnostics_channel` module. The Sentry Node.js SDK uses this built-in module to instrument Node.js fetch requests. Some older Node.js versions do not have the `diagnostics_channel` API, which may lead to build errors when attempting to bundle your code.

Most bundlers have an option to externalize specific modules (like `diagnostics_channel`):

* [Externals in Webpack](https://webpack.js.org/configuration/externals/)
* [External in Vite](https://vitejs.dev/config/ssr-options.html#ssr-external)
* [External in esbuild](https://esbuild.github.io/api/#external)
* [External in Rollup](https://rollupjs.org/configuration-options/#external)

Terser plugin build errors

If you're using a custom webpack plugin that utilizes Terser or another minifier, you might encounter build errors due to a known webpack bug. This issue has been fixed in webpack version 5.85.1 and later.

For more details about this issue, see [webpack/terser-plugin build errors](https://github.com/getsentry/sentry-javascript/issues/14091).

pnpm: Resolving 'import-in-the-middle' external package errors

When using pnpm, you might encounter errors related to packages that can't be external, particularly with packages like `import-in-the-middle` and `require-in-the-middle`. These errors typically occur due to pnpm's strict dependency management and hoisting behavior.

While adding these packages as direct dependencies might remove the warning messages, it often doesn't resolve the underlying functionality issues:

```bash
pnpm add import-in-the-middle require-in-the-middle
```

As a workaround, create or modify `.npmrc` in your project root. First, try to specifially hoist the dependencies in question:

`.npmrc`

```ini
public-hoist-pattern[]=*import-in-the-middle*
public-hoist-pattern[]=*require-in-the-middle*
```

If that doesn't work, you can also tell pnpm to hoist all dependencies:

`.npmrc`

```ini
shamefully-hoist=true
```

**Note**: While `shamefully-hoist=true` usually isn't the ideal solution from a dependency management perspective, it's sometimes necessary for compatibility with certain packages that expect Node.js module resolution behavior similar to npm or yarn.

If you need additional help, you can [ask on GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose). Customers on a paid plan may also contact support.
