From bb513e062273edaa7f0ab9d272a212d72062af43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 28 Oct 2025 13:39:51 +0100 Subject: [PATCH 1/4] ndk: expose init return code from sentry_init --- ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java | 9 ++++++--- ndk/lib/src/main/jni/sentry.c | 13 +++++++------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java b/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java index d43ac268a..5c7c914eb 100644 --- a/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java +++ b/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java @@ -10,7 +10,10 @@ public final class SentryNdk { private SentryNdk() {} - private static native void initSentryNative(@NotNull final NdkOptions options); + /** + * Initializes sentry-native and returns 0 on success, non-zero on failure. + */ + private static native int initSentryNative(@NotNull final NdkOptions options); private static native void shutdown(); @@ -19,9 +22,9 @@ private SentryNdk() {} * * @param options the SentryAndroidOptions */ - public static void init(@NotNull final NdkOptions options) { + public static int init(@NotNull final NdkOptions options) { loadNativeLibraries(); - initSentryNative(options); + return initSentryNative(options); } /** Closes the NDK integration */ diff --git a/ndk/lib/src/main/jni/sentry.c b/ndk/lib/src/main/jni/sentry.c index 827ec5bab..ff05ba847 100644 --- a/ndk/lib/src/main/jni/sentry.c +++ b/ndk/lib/src/main/jni/sentry.c @@ -247,11 +247,11 @@ static void send_envelope(sentry_envelope_t *envelope, void *data) { sentry_envelope_free(envelope); } -JNIEXPORT void JNICALL +JNIEXPORT jint JNICALL Java_io_sentry_ndk_SentryNdk_initSentryNative( - JNIEnv *env, - jclass cls, - jobject sentry_ndk_options) { + JNIEnv *env, + jclass cls, + jobject sentry_ndk_options) { jclass options_cls = (*env)->GetObjectClass(env, sentry_ndk_options); jmethodID outbox_path_mid = (*env)->GetMethodID(env, options_cls, "getOutboxPath", "()Ljava/lang/String;"); @@ -355,8 +355,8 @@ Java_io_sentry_ndk_SentryNdk_initSentryNative( jfloat traces_sample_rate = (jfloat) (*env)->CallFloatMethod(env, sentry_ndk_options, traces_sample_rate_mid); sentry_options_set_traces_sample_rate(options, traces_sample_rate); - sentry_init(options); - return; + int rv = sentry_init(options); + return (jint) rv; fail: if (!transport_owns_path) { @@ -366,6 +366,7 @@ Java_io_sentry_ndk_SentryNdk_initSentryNative( sentry_transport_free(transport); } sentry_options_free(options); + return (jint) -1; } JNIEXPORT void JNICALL From 5bb7b059e9b9da41c7646b0078928ebff3a17cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 28 Oct 2025 13:43:14 +0100 Subject: [PATCH 2/4] changelog: note SentryNdk.init return code --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 506807466..fc79c6a80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Breaking changes**: - If you use a narrow string path interface (for instance, `sentry_options_set_database_path()`) on _Windows_ rather than one of the wide string variants (`sentry_options_set_database_pathw()`), then the expected encoding is now UTF-8. ([#1413](https://github.com/getsentry/sentry-native/pull/1413)) +- Android NDK: `SentryNdk.init(NdkOptions)` now returns an `int` (0 success, non-zero failure) instead of `void`, exposing the result of `sentry_init()`. ([#1430](https://github.com/getsentry/sentry-native/pull/1430)) **Fixes**: From c0d3d4d5bba5ee0c3d5417d6f3bcb621d46d43c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hanno=20J=2E=20G=C3=B6decke?= Date: Tue, 28 Oct 2025 13:45:12 +0100 Subject: [PATCH 3/4] formatting --- ndk/lib/src/main/jni/sentry.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ndk/lib/src/main/jni/sentry.c b/ndk/lib/src/main/jni/sentry.c index ff05ba847..6be3765c3 100644 --- a/ndk/lib/src/main/jni/sentry.c +++ b/ndk/lib/src/main/jni/sentry.c @@ -249,9 +249,9 @@ static void send_envelope(sentry_envelope_t *envelope, void *data) { JNIEXPORT jint JNICALL Java_io_sentry_ndk_SentryNdk_initSentryNative( - JNIEnv *env, - jclass cls, - jobject sentry_ndk_options) { + JNIEnv *env, + jclass cls, + jobject sentry_ndk_options) { jclass options_cls = (*env)->GetObjectClass(env, sentry_ndk_options); jmethodID outbox_path_mid = (*env)->GetMethodID(env, options_cls, "getOutboxPath", "()Ljava/lang/String;"); From 92ca3911c2aeb9ad4436c9b789c88eba0d4c5d21 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Mon, 1 Dec 2025 11:06:42 +0100 Subject: [PATCH 4/4] Address PR feedback --- CHANGELOG.md | 6 ++++- .../java/io/sentry/ndk/SentryNdkTest.java | 24 +++++++++++++++++++ .../main/java/io/sentry/ndk/SentryNdk.java | 14 +++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c239624e..0b19e459e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +** Breaking Changes ** + +- Android NDK: `SentryNdk.init(NdkOptions)` now throws an `Exception` if init fails (non-zero return code) rather than silently swallowing the error. ([#1430](https://github.com/getsentry/sentry-native/pull/1430)) + + **Features**: - Add custom attributes API for logs. When `logs_with_attributes` is set to `true`, treats the first `varg` passed into `sentry_logs_X(message,...)` as a `sentry_value_t` object of attributes. ([#1435](https://github.com/getsentry/sentry-native/pull/1435)) @@ -20,7 +25,6 @@ **Breaking changes**: - If you use a narrow string path interface (for instance, `sentry_options_set_database_path()`) on _Windows_ rather than one of the wide string variants (`sentry_options_set_database_pathw()`), then the expected encoding is now UTF-8. ([#1413](https://github.com/getsentry/sentry-native/pull/1413)) -- Android NDK: `SentryNdk.init(NdkOptions)` now returns an `int` (0 success, non-zero failure) instead of `void`, exposing the result of `sentry_init()`. ([#1430](https://github.com/getsentry/sentry-native/pull/1430)) **Features**: diff --git a/ndk/lib/src/androidTest/java/io/sentry/ndk/SentryNdkTest.java b/ndk/lib/src/androidTest/java/io/sentry/ndk/SentryNdkTest.java index 76f4ca0fa..ad9907740 100644 --- a/ndk/lib/src/androidTest/java/io/sentry/ndk/SentryNdkTest.java +++ b/ndk/lib/src/androidTest/java/io/sentry/ndk/SentryNdkTest.java @@ -65,6 +65,30 @@ public void shutdownDoesNotFail() throws IOException { // it does not crash } + @Test(expected = IllegalStateException.class) + public void initThrowsException() throws IOException { + final TemporaryFolder temporaryFolder = TemporaryFolder.builder().build(); + temporaryFolder.create(); + final File outboxPath = temporaryFolder.newFolder("outboxPath"); + + //noinspection DataFlowIssue + final NdkOptions options = + new NdkOptions( + null, + true, + outboxPath.getAbsolutePath(), + "1.0.0", + "production", + "dist", + 100, + "io.sentry.ndk"); + + // when initialized with a NULL dsn + SentryNdk.init(options); + + // then it does crash + } + @Test public void messageCaught() throws IOException { final TemporaryFolder temporaryFolder = TemporaryFolder.builder().build(); diff --git a/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java b/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java index 5c7c914eb..72046377f 100644 --- a/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java +++ b/ndk/lib/src/main/java/io/sentry/ndk/SentryNdk.java @@ -12,6 +12,9 @@ private SentryNdk() {} /** * Initializes sentry-native and returns 0 on success, non-zero on failure. + * + * @return -1 if an JNI or options configuration issue occurred, 1 if sentry native itself failed + * to initialize */ private static native int initSentryNative(@NotNull final NdkOptions options); @@ -21,10 +24,17 @@ private SentryNdk() {} * Init the NDK integration * * @param options the SentryAndroidOptions + * @throws IllegalStateException if sentry-native couldn't be initialized */ - public static int init(@NotNull final NdkOptions options) { + public static void init(@NotNull final NdkOptions options) { loadNativeLibraries(); - return initSentryNative(options); + final int returnCode = initSentryNative(options); + if (returnCode > 0) { + throw new IllegalStateException( + "A sentry-native internal init error occurred, please check the logs for more details."); + } else if (returnCode < 0) { + throw new IllegalStateException("A sentry-native setup failure occurred"); + } } /** Closes the NDK integration */