Skip to content
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

Setting enableNativeCrashHandling to false does not disable native reports #317

Closed
4 of 11 tasks
Dave0921 opened this issue Feb 24, 2021 · 10 comments
Closed
4 of 11 tasks

Comments

@Dave0921
Copy link

Platform:

  • Dart
  • Flutter Android or iOS
  • Flutter Web

IDE:

  • VSCode
  • IntelliJ/AS
  • XCode
  • Other, which one?

split-debug-info and obfuscate (Flutter Android or iOS) or CanvasKit (Flutter Web):

  • Enabled
  • Disabled

Platform installed with:

  • pub.dev
  • GitHub

Output of the command flutter doctor -v below:

[✓] Flutter (Channel stable, 1.22.5, on Mac OS X 10.15.6 19G2021 darwin-x64, locale en-CA)
    • Flutter version 1.22.5 at -----------------
    • Framework revision 7891006299 (3 months ago), 2020-12-10 11:54:40 -0800
    • Engine revision ae90085a84
    • Dart version 2.10.4

 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at -----------------
    • Platform android-30, build-tools 30.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.0

[✓] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin installed
    • Dart plugin version 201.9245
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] VS Code (version 1.53.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.19.0

[✓] Connected device (1 available)
    • iPhone 12 (mobile) • BEFBD9BF-8751-497F-A1F5-7465631F3641 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-3
      (simulator)

• No issues found!

The version of the SDK (See pubspec.lock):
4.0.5


I have the following issue:

Setting enableNativeCrashHandling to false does not disable native Android/iOS errors from being reported to sentry.io.

Steps to reproduce:

  1. Set enableNativeCrashHandling to false in example app
  2. Run app
  3. Press Swift fatalError button (app crashes)
  4. Open app again
  5. Press Swift fatalError button again (app crashes)

Actual result:

  • Crash report appears in sentry.io

Expected result:

  • Crash report should not appear in sentry.io
@marandaneto
Copy link
Contributor

@Dave0921 thanks for reporting this.

so the enableNativeCrashHandling feature is not totally disabling it, but actually disabling the signal handlers, eg for Android the UncaughtExceptionHandler, which means, if you do a null pointer exception, the SDK won't capture automatically for you, but if you do Sentry.captureException(ex), it will.

indeed, enableNativeCrashHandling is not being applied on iOS, because there's no way on sentry-cocoa right now to opt-out of the signal handler (KSCrash), I'll raise an issue about that, thanks.

@marandaneto
Copy link
Contributor

marandaneto commented Feb 24, 2021

if you don't want Native events, I'd recommend using the sentry package instead which is Flutter/Native SDKs free.

@Dave0921
Copy link
Author

@marandaneto Thanks for the suggestion. Unfortunately for my use case, I also require Flutter errors to be reported as well.

@MisterJimson
Copy link

For what its worth, I'm looking for this so that when debugging we don’t send native crashes to Sentry, but in release builds, we do send. Trying to achieve this without needing to change anything in the local setup.

@marandaneto
Copy link
Contributor

marandaneto commented Feb 24, 2021

For what its worth, I'm looking for this so that when debugging we don’t send native crashes to Sentry, but in release builds, we do send. Trying to achieve this without needing to change anything in the local setup.

fair case but for this, I'd consider not initing the sentry_flutter itself, so problem solved.

@marandaneto
Copy link
Contributor

@bruno-garcia
Copy link
Member

@Dave0921 could you please describe why do you need to disable the native crash reports?

I believe there might be a sign that we are missing a different feature to solve your use case, like adding an environment=development so you don't get these crashes during development affecting your release health like @MisterJimson mentioned above. Or is this a different use case?

There are side effects by disabling the native crashes only like @marandaneto said it'll affect your crash-free stats.

@MisterJimson
Copy link

MisterJimson commented Mar 10, 2021

@Dave0921 and I work together, and I can speak about our goals. We have accomplished them with some of the advice in this thread.

  • When running the app in debug mode, send no data to Sentry
  • When the app is running in release mode, send both native events/crashes and Dart level events/exceptions.
  • When the app is running in release mode, ensure native events/crashes that happen before the Flutter engine is initialized are caught and sent to Sentry.
  • Allow Sentry environment to be changed and set at runtime

The first 2 are fairly simple and can be achieved by using the kReleaseMode in Flutter. If kReleaseMode is false, don’t call SentryFlutter.init.

The third is tricky when combined with the first requirement, but we found a solution.

Android solution below. Only outstanding issue is that the environment for startup crashes will always be Production. We are fine with this.

import android.content.Context
import androidx.startup.Initializer
import io.sentry.android.core.SentryAndroid
import io.sentry.android.core.SentryAndroidOptions

class LoggerInitializer : Initializer<String> {
    override fun create(context: Context): String {
        SentryAndroid.init(context) { options: SentryAndroidOptions ->
            options.setBeforeSend { event, _ ->
                // If the application is in debug mode, discard the events
                if (BuildConfig.DEBUG) return@setBeforeSend null else return@setBeforeSend event
            }
        }
        return ""
    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        return ArrayList()
    }
}

<meta-data
            android:name="io.sentry.environment"
            android:value="Production" />
        <!-- Cancels the automatic initialization of the Sentry SDK -->
        <meta-data android:name="io.sentry.auto-init" android:value="false" />

iOS is similar.

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private static let SentryDSN = "SentryDSN"
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        /// Start native Sentry SDK before app launch to capture on app launch crashes only on release build
        if !_isDebugAssertConfiguration() {
            guard let dsn = Bundle.main.object(
                forInfoDictionaryKey: AppDelegate.SentryDSN
            ) else {
                NSException.raise(
                    NSExceptionName.invalidArgumentException,
                    format:"The value for key %@ is not set in Info.plist",
                    arguments: getVaList([
                        Self.SentryDSN,
                    ]))
                return false
            }

            guard let dsnString = dsn as? String else {
                NSException.raise(
                    NSExceptionName.invalidArgumentException,
                    format:"The value for key %@ is not a <string> type: %@",
                    arguments: getVaList([
                        Self.SentryDSN,
                        String(describing: dsn),
                    ]))
                return false
            }

            SentrySDK.start { options in
                options.dsn = dsnString
                /// Active config environment name cannot be accessed on the native level
                options.environment = "Production"
            }
        }

@marandaneto
Copy link
Contributor

marandaneto commented Mar 10, 2021

thanks, the 3rd item should be easier to set up, and its been tracked here #265
environment could also be mutated in the beforeSend callback

@bruno-garcia
Copy link
Member

Thanks @MisterJimson for the detailed description. Makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants