Skip to content

React app wrapped in Cordova: both Sentry libs seem to cancel each other #324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
igorsantos07 opened this issue Jan 3, 2024 · 15 comments
Closed

Comments

@igorsantos07
Copy link

igorsantos07 commented Jan 3, 2024

This is a follow up of the old #307. We are still unable to get Sentry to run on the Cordova shell of our React app (which runs both on the browser and on native environments via Cordova loading the web code inside of it).

It took me quite a while to get back to this because of #311, which developed into #320 - and I'm unable to make sure that is gone, since I can't even say for sure if the plugin is working as expected.

Environment

  • sentry-cordova 1.2.0 (which seems to require 7.34.0 from the inner packages)
  • sentry/react 7.34.0
  • Intel macOS 13.4.1
  • cordova 12.0.0
  • cordova-ios 6.3.0 (testing on an iPhone 14 emulator)
  • cordova-android 12.0.1 (haven't tested on Android yet)

Expected Result

Errors coming from the React side would report the same way we already have from the web-based version.
Errors coming from the Cordova side would report with different tags and details, as configured in the Cordova code.

Actual Result

Edit: after writing everything under the separator below, I found out about the debug option. Enabling it from the Cordova side I see the Dedupe processor drops any single call to captureMessage(), for instance, and no network call is done. This happens from the Cordova and the Sentry libs. Multiple calls with the same message start to yield a warning about being a duplicate of a previously captured event......... But nothing ever showed to my Issues panel (and yep, my sampling rate is 100%, as you can see below where I can get stuff to show up by simply skipping the Cordova SDK).
And even then... the capture call returns an new event ID, every time. Does it make sense?
I couldn't enable debug on the React side, it complains about being a non-debug bundle; I'm using the NPM sentry/react package there, so not sure what I did wrong.


Trying to be sure what's going on, I initialized the React side with window.SentryReact = Sentry, and similarly on the Cordova side.

If I comment out the Cordova Sentry.init(), I can (obviously) see window.Sentry.SDK_VERSION == '7.34.0' (thus, React package). Sentry reports as usual, e.g. with window.Sentry.captureMessage('a') causing some extra network calls to your servers.

However, when both init calls are present (with the Cordova one coming first, since it's the one who loads the React code), only the Cordova version is reporting native errors.
In this case, Sentry and SentryCordova are the Cordova SDK, while SentryReact remains "nameless" (no SDK_NAME) but with SDK_VERSION == '7.34.0'.
No call to captureMessage('b') yields anything in my Issues panel (nor any network call), from any of the three variables, but Sentry.nativeCrash() does yield a native report on my panel, after the app is restarted! Maybe that works because the report happens right on load, before the React code lands?
No problem shows up on the JS console, when inspecting the Cordova app from Safari (even if I call captureMessage('b') from the console).
Also, setting window.Sentry = null right after the Cordova init leads to it still being null after React loads. It also doesn't help SentryReact to capture anything. I guess Sentry places itself in the global scope before initialization?

Further thoughts

I wonder if such issues happen because Sentry may rely on the global window.Sentry, which could be including conflicting code? Or they both cling to the same error handler, instead of stacking different handlers... Although I was previously instructed to be sure I was running the same inner-dependencies, which it seems I am.

I'm open to suggestions on this scenario, since if we tell the React code to skip Sentry.init() when window.Sentry already has something in it, we will end up having very different reports between the web app and the cordova-wrapped one - we will miss Replay, Browser Tracing and other goodies (including React-specific features). And on the other hand, with only the React library enabled (as we are now), we lose (are losing!) any native errors.

I wonder if it would be possible to have the Cordova plugin running but only listening to native issues, instead of living in the JS context as well? I found the enableNative option, but no JS counterpart.

@lucas-zimerman
Copy link
Collaborator

Thanks for opening this issue!
would you mind uploading a minimal reproduction of this issue you are facing?

@lucas-zimerman lucas-zimerman moved this from Needs Discussion to Needs More Information in Mobile SDKs Jan 5, 2024
@igorsantos07
Copy link
Author

Thanks for not telling me to walk away after such a edge case 😂 will try

@igorsantos07
Copy link
Author

igorsantos07 commented Jan 6, 2024

Have fun

I think you'll need to do the following to run it:

  1. move www/env.js.sample to www/env.js, placing your test DSN there
  2. [optional] make sure you use the same DSN for both the Cordova and Browser configuration, for maximum enjoyment - you'll notice, for instance, that logger isn't present on the Cordova report as one would expect
  3.  npx cordova platform add [[android|ios]]
     npx cordova plugin add sentry-cordova    # here I guess you know what to do haha
     npx cordova run
    

Instead of the React SDK, I went with the vanilla browser one, so I wouldn't need to setup NPM, React bundler or the likes. Turns out the conflict is still there, so... 🤷‍♂️
Also, sorry for the terrible styles on those default Cordova buttons lol

Relevant code is all at www/index.html. I left a TODO note where you can comment some lines and see the changing behavior between the SDKs.

@lucas-zimerman
Copy link
Collaborator

No worries, the important thing is the reproduction of it, the sample helps us alot on the investigation to give you a faster resolution of the issue.
Thank you for helping us!, I'll give you an answer soon.

@lucas-zimerman lucas-zimerman moved this from Needs More Information to Needs Investigation in Mobile SDKs Jan 19, 2024
Copy link

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

Copy link

github-actions bot commented Mar 9, 2024

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@igorsantos07
Copy link
Author

stale-proof comment

@igorsantos07
Copy link
Author

igorsantos07 commented Aug 11, 2024

Any chance this could be looked into in the foreseeable future? 😓 I've posted the reproducible example 7 months ago :/

If it's not fixable, at least explain why... My knowledge wasn't enough to see a path for a fix, but I'm no Sentry-internals expert either. If this isn't fixable, I guess it would mean we will never be able to use Sentry to catch Cordova errors which, while rare in our scenario, are a possibility that should be covered by the product, which we've been using for a year and a half already.

@lucas-zimerman
Copy link
Collaborator

I am sorry for the late response :/
The way the Cordova SDK works doesn't allow for it to be started along with another SDK, but that is not going to be a problem with the React SDK since the initialization of it only calls the same initialization that the Cordova SDK calls + it changes the SDK name on the events.

So you only need to Initialize the Cordova SDK and if needed you can also add the React specific integrations on the Cordova SDK initialization.

@kahest kahest moved this from Needs Investigation to Needs More Information in Mobile SDKs Aug 30, 2024
Copy link

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@igorsantos07
Copy link
Author

Oh well. Thanks for trying, at least.

Any guidance on how to add the React specific integrations to the Cordova SDK?

Copy link

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@igorsantos07
Copy link
Author

:(

@lucas-zimerman
Copy link
Collaborator

Sorry for the late response, but if you need here is a cordova sample using React:
https://github.com/lucas-zimerman/SentryCordovaReactSample

The secret is to use the exact same version of @sentry/core that the SDK uses (on latest verison is 7.119.1).

After adding @Sentry/React, you will need to initialize Sentry Cordova, with that, add the Sentry/React integrations, here is a sample snippet for that

import * as Sentry from "sentry-cordova";
import * as SentryReact from "@sentry/react";

function startApp() {
    Sentry.init({
        debug: true,
        dsn: 'https://[email protected]/5627302',
        tracesSampleRate: 1,
        enableTracing: true,
        replaysOnErrorSampleRate: 1,
        replaysSessionSampleRate: 1,
        integrations: [
            SentryReact.reactRouterV6BrowserTracingIntegration({ // <----- React Integration
                useEffect,
                useLocation,
                useNavigationType,
                createRoutesFromChildren,
                matchRoutes
            }),
            Sentry.replayIntegration(),
        ]
    });
    ReactDOM.render(<App />, document.getElementById("app"));
}

if you are using JavaScript only, you could retrieve Sentry/Cordova using cordova.require("sentry-cordova.Sentry")

and Sentry/React with const SentryReact = require("@sentry/react");
The rest should be similar to the snippet code.

In general, all the calls will be made to Sentry/Cordova, and only react specific calls to sentry/react.

Let me know if you have any questions

Copy link

This issue has gone three weeks without activity. In another week, I will close it.

But! If you comment or otherwise update it, I will reset the clock, and if you label it Status: Backlog or Status: In Progress, I will leave it alone ... forever!


"A weed is but an unloved flower." ― Ella Wheeler Wilcox 🥀

@github-project-automation github-project-automation bot moved this from Needs More Information to Done in Mobile SDKs Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

No branches or pull requests

3 participants