bugsnag-unity icon indicating copy to clipboard operation
bugsnag-unity copied to clipboard

Notify handled android java exceptions

Open troy-lamerton opened this issue 3 years ago • 4 comments

Description

In our Unity game, we have a lot of android plugins that need to report exceptions.

Since we use the Unity SDK, there is no obvious way to report these java/kotlin exceptions.

Describe the solution you'd like

Any way to send a java/kotlin exception to the bugsnag dashboard.

A simple api could be: public void Notify(AndroidJavaObject jvmException)

Describe alternatives you've considered

Calling Bugsnag.Notify with stacktrace string

Bugsnag.Notify(new Exception("<my android stacktrace>"))

Result: I think the message is not retraced? (class names will show a.b.c.d)

Calling the bugsnag android SDK via reflection:

package com.demo.util

import android.content.Context
import android.util.Log
import com.unity3d.player.UnityPlayer
import java.lang.Exception
import java.lang.reflect.InvocationTargetException

object BugsnagTest {
    @JvmStatic
    fun reportException() {
        val clazz = Class.forName("com.bugsnag.android.Bugsnag")

        // required, otherwise notify() will throw an exception
        val bsgInit = clazz.getDeclaredMethod("init", Context::class.java)
        safeInvoke {
            bsgInit(null, UnityPlayer.currentActivity)
        }

        val bsgNotify = clazz.getDeclaredMethod("notify", java.lang.Throwable::class.java)

        val ex = Exception("hello")
        safeInvoke {
            bsgNotify(null, ex)
        }
    }

    private fun safeInvoke(block: () -> Unit) {
        try {
            block()
        } catch (ex: InvocationTargetException) {
            Log.wtf("BugsnagTest", ex.cause)

        } catch (ex: Throwable) {
            Log.wtf("BugsnagTest", ex)
        }
    }
}

Result: This does work.. but any native crash that happens after this (e.g. SIGTRAP) is not reported to bugsnag.

troy-lamerton avatar Mar 27 '21 08:03 troy-lamerton

Hey @troy-lamerton As you have seen, accessing the Unity notifier to manually notify on handled java exceptions is not currently supported. We are however looking at alternative ways to do this. At the moment we don't have a definite timeline but we will post here with any updates.

johnkiely1 avatar Mar 29 '21 09:03 johnkiely1

Hey @johnkiely1, I would like to know if the Unity notifier only reports exceptions on Unity scenes. It the game has portions of code that are native are exceptions reported? Would it be possible to use two integrations on the same project? ( https://docs.bugsnag.com/platforms/android/ and https://docs.bugsnag.com/platforms/unity/) Thanks

interpegasus avatar May 11 '21 17:05 interpegasus

Hey @interpegasus,

Unhandled native exceptions are captured when using the Unity notifier. This applies to Android iOS and MacOs. This would occur by default once you have integrated Bugsnag into your application. https://docs.bugsnag.com/platforms/unity/#reporting-unhandled-errors

The Android/iOS/macOs notifiers are used under the hood by the Unity notifier to do this.

johnkiely1 avatar May 14 '21 12:05 johnkiely1

We have a solution internally and are testing it at the moment. So this is lower priority for us now.

Solution goes like this:

  1. Log.getStackTraceString to serialize a Java/Kotlin Throwable to a string
  2. Send string to Unity
  3. Use new AndroidJavaException() to create a C# exception from the Throwable stacktrace string
  4. Notify bugsnag of this exception, just like any other C# exception

Code snippet for steps 1 and 2:

    @AnyThread
    @JvmStatic
    fun reportPluginError(ex: Throwable) {
        // getStackTraceString: exception class, message and stacktrace
        val readableException = Log.getStackTraceString(ex).trim().replace("\t", "    ")
        UnityPlayer.UnitySendMessage("NativePluginListener", "ReportNativeWarning", readableException)
    }

Would be good to keep this issue open to track implementing the feature in the Bugsnag source code.

troy-lamerton avatar Jun 15 '21 03:06 troy-lamerton