Identify potential interference with Sentry.captureMessage(...) or Sentry.captureException(...) functions within a JavaScript application, such as being obstructed by an ad-blocking extension

Overview

Our Javascript application uses Angular and TypeScript, with Sentry.io for error reporting. If an error occurs, a custom modal allows users to leave a message, which should be sent to Sentry when they click submit.

Issue

We have noticed that messages are not being received by Sentry if it is inaccessible, such as being blocked by an ad blocker plugin in the browser.

Objective

Our goal is to provide users with instructions to contact support if Sentry is unavailable, or allow them to send a message through Sentry but provide alternative support options if the message sending fails.


Approaches Attempted

We have explored using Sentry's Sentry.captureMessage(…) and Sentry.flush(…), but these methods do not indicate if the POST request was successful. We developed a workaround by checking if Sentry is blocked internally.

public sentryIsBlocked() : boolean | null {
    const client = Sentry.getCurrentHub().getClient();

    // Check if Sentry is reachable
    if (!client) return null;

    const numberOfNetworkSessionErrors = (client as any)['_outcomes']['network_error:session'];

    return !!numberOfNetworkSessionErrors && numberOfNetworkSessionErrors > 0;
}

While this solution works, there are drawbacks:

  • It may break with Sentry updates as it relies on non-public API objects.
  • The method returns true if any past request to Sentry had issues, which does not guarantee current success.

Inquiry

Is there a way to determine if a POST request made by Sentry.captureMessage(…) or Sentry.captureException(…) encounters an error?

Answer №1

If you're looking to securely tunnel data through your own backend, Sentry has got you covered. You can find detailed documentation on how to do this here:

By setting up the SDK to send data to a specific endpoint in your backend, you can bypass ad blockers that may block direct access to Sentry's ingestion endpoint.

A prime example of tunneling in action is showcased in the NuGet Trends app, where they use the endpoint /t for this purpose.

If you are using Sentry for ASP.NET Core on the backend, integrating it is as simple as adding a single line of code:

https://github.com/dotnet/nuget-trends/blob/3b12f722505aca5423e469449549e46ab4986f6c/src/NuGetTrends.Web/Startup.cs#L120

app.UseSentryTunneling("/t");

On the client side, configure the tunnel like so:

tunnel: “/t”

Even Angular projects, such as the one in NuGet Trends, can benefit from this setup: https://github.com/dotnet/nuget-trends/blob/3b12f722505aca5423e469449549e46ab4986f6c/src/NuGetTrends.Web/Portal/src/app/app.module.ts#L22

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular2: Learn how to dynamically create input fields when a button is clicked

My current challenge involves replicating input fields on click of a button. I have a set of input fields where data can be entered, and then I need to add another set of the same fields for additional data. There needs to be a way to remove these replicat ...

Command to update a document in AWS DynamoDB using the Document Client

While attempting to utilize the UpdateCommand feature within the AWS DynamoDB documentation, I encountered various challenges due to its lack of detailed explanation and difficulty in implementation. My aim was to employ the update command to seamlessly t ...

Combining and mapping arrays in Javascript to form a single object

I am using the following firebase function this.sensorService.getTest() .snapshotChanges() .pipe( map(actions => actions.map(a => ({ [a.payload.key]: a.payload.val() }))) ).subscribe(sensors => { ...

Default exports are not supported in TypeScript

I'm encountering issues with my Laravel + Vite + Vue 3 project. I followed the installation instructions in the documentation and everything works fine when the project is separated from Laravel and Vite. However, I'm facing a problem where TypeS ...

How can we strengthen the type checking when defining the sorting function for json properties?

When dealing with a json structure from a service that contains .attributes json values, I often find myself needing to sort either by id from the DTO or by several attributes from the IContactsAttributes. The microservice returns this specific structure: ...

Broadening Cypress.config by incorporating custom attributes using Typescript

I'm attempting to customize my Cypress configuration by including a new property using the following method: Cypress.Commands.overwrite('getUser', (originalFn: any) => { const overwriteOptions = { accountPath: `accounts/${opti ...

What is the best way to combine two arrays and generate a new array that includes only unique values, similar to a Union

Here are two arrays that I have: X = [ { "id": "123a", "month": 5, "markCount": 75 }, { "id": "123b", "month": 6, "markCount": 85 ...

What could be the reason for my Angular 2 app initializing twice?

Can someone help me figure out why my app is running the AppComponent code twice? I have a total of 5 files: main.ts: import { bootstrap } from '@angular/platform-browser-dynamic'; import { enableProdMode } from '@angular/core'; impor ...

Tips for displaying HTML content dynamically in React using TypeScript after setting a stateVariable

To render an HTML block after successfully setting a state variable, I have defined my state variables and functions below. The code snippet is as follows: const formService = new FormService(); const [appointmentDate, setAppointmentDate] = us ...

Use JavaScript's Array.filter method to efficiently filter out duplicates without causing any UI slowdown

In a unique case I'm dealing with, certain validation logic needs to occur in the UI for specific business reasons[...]. The array could potentially contain anywhere from several tens to hundreds of thousands of items (1-400K). This frontend operation ...

NG0303: Unable to establish a connection with 'ngbTooltip' as it is not recognized as a valid property of 'button'

ERROR: 'NG0303: Can't bind to 'ngbTooltip' since it isn't a known property of 'button'.' Encountering this issue in my Angular 12 project when running local tests, the ngbTooltip error is present in all .spec files. ...

Could not load ngx-restangular due to an error: (SystemJS) Module not yet loaded while trying to load "@angular/core"

Recently, I made the switch from using the AngularJS 'restangular' library to the Angular 'ngx-restangular' library during an upgrade from AngularJS to Angular. However, after the transition, I encountered an unexpected error along wit ...

I want my Angular 2 application to redirect to the appropriate page when a user who is logged out attempts to access a page that requires them to be logged in

When a user is logged out in Angular 2 router and they try to navigate to a page that requires them to be logged in, I need the app.ts file to redirect them. I am utilizing typescript along with angular 2. Oddly enough, the redirection works for certain ...

Navigating to the end of a list using Angular's scroll feature

I'm trying to figure out how to automatically scroll to the bottom of a list in TypeScript, can someone help me with this? Here's a similar example I found that uses jQuery (I specifically need it in TypeScript): Scroll to bottom of list wit ...

Retrieve unique values based on two or more criteria from an array in TypeScript

Presented here is an array. https://i.stack.imgur.com/zHXim.png The desired pattern is: https://i.stack.imgur.com/EGUiM.png I am interested in retrieving unique "CityRef" and "City". Subsequently, locating all items associated with them. ...

organize the values based on their priority using reactjs

I'm facing a challenge involving two arrays of objects: array1 and array2. I need to display only three values from both arrays, with priority given to array1. The requirements are as follows: if array1 contains 3 elements, all three should be shown. ...

Error message: The types in React Redux typescript are incompatible and cannot be assigned to each other

I recently converted my React App to TypeScript and encountered an error that I'm having trouble understanding. Any help would be greatly appreciated. Here is the code for my "mapStateToProps" function: function mapStateToProps(state: AppState): MapS ...

Solve the TypeScript path when using jest.mock

I am currently in the process of adding unit tests to a TypeScript project that utilizes compilerOptions.paths. My goal is to mock an import for testing purposes. However, I have encountered an issue where jest is unable to resolve the module to be mocked ...

Is there a way to programmatically add a timestamp to a form in Angular6?

Is there a way to automatically populate new forms with the current datetime value? this.editForm.patchValue({ id: chatRoom.id, creationDate: chatRoom.creationDate != null ? chatRoom.creationDate.format(DATE_TIME_FORMAT) : null, roo ...

The utilization of the Angular date pipe significantly impacts the way dates are

When I use the pipe date:'MM/dd/YYYY' to display the date 2022-01-01T00:00:00, it shows as 1/01/2021 instead of 1/01/2022. This issue only occurs with this specific date. Why does this happen? The value of pharmacyRestrictionDate is 2022-01-01T0 ...