From 518e2e9d72b235a25210c553cf72cc7b1f3ddad1 Mon Sep 17 00:00:00 2001 From: Delisa Mason Date: Mon, 1 Jul 2019 12:32:42 +0100 Subject: [PATCH] fix(android): Parse java exception name when message missing Not all Java exceptions have messages, so the default should be to set the class and java exception parsing style if the error class is detected. --- CHANGELOG.md | 3 +++ bugsnag-android | 2 +- src/BugsnagUnity/Payload/Exception.cs | 14 +++++++++++++- tests/BugsnagUnity.Tests/ExceptionTests.cs | 22 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a91928924..27cd0f715 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ ### Bug fixes +* (Android) Fix error class and message parsing for uncaught Java exceptions + without message contents + [#159](https://github.com/bugsnag/bugsnag-unity/pull/159) * Show report metadata added using `Bugsnag.Metadata.Add()` in native crash reports [#157](https://github.com/bugsnag/bugsnag-unity/pull/157) diff --git a/bugsnag-android b/bugsnag-android index f89058aa1..4231fd669 160000 --- a/bugsnag-android +++ b/bugsnag-android @@ -1 +1 @@ -Subproject commit f89058aa15ed211c14c071587f664b9565603608 +Subproject commit 4231fd66988080ac8cae6a20a31cdd582d3880ef diff --git a/src/BugsnagUnity/Payload/Exception.cs b/src/BugsnagUnity/Payload/Exception.cs index c3f54b657..4dba07dd6 100644 --- a/src/BugsnagUnity/Payload/Exception.cs +++ b/src/BugsnagUnity/Payload/Exception.cs @@ -133,16 +133,28 @@ public static Exception FromUnityLogMessage(UnityLogMessage logMessage, System.D { var errorClass = match.Groups["errorClass"].Value; var message = match.Groups["message"].Value.Trim(); + // Exceptions starting with "AndroidJavaException" are uncaught Java exceptions reported + // via the Unity log handler if (errorClass == AndroidJavaErrorClass) { match = Regex.Match(message, ErrorClassMessagePattern, RegexOptions.Singleline); + // If the message matches the "class: message" pattern, then the Java class is followed + // by a description of the Java exception. These two values will be used as the error + // class and message. if (match.Success) { errorClass = match.Groups["errorClass"].Value; message = match.Groups["message"].Value.Trim(); - lines = new StackTrace(logMessage.StackTrace, StackTraceFormat.AndroidJava).ToArray(); } + else + { + // There was no Java exception description, so the Java class is the only content in + // the message. + errorClass = message; + message = ""; + } + lines = new StackTrace(logMessage.StackTrace, StackTraceFormat.AndroidJava).ToArray(); handledState = HandledState.ForUnhandledException(); } return new Exception(errorClass, message, lines, handledState); diff --git a/tests/BugsnagUnity.Tests/ExceptionTests.cs b/tests/BugsnagUnity.Tests/ExceptionTests.cs index d3d99e028..1eb29b425 100644 --- a/tests/BugsnagUnity.Tests/ExceptionTests.cs +++ b/tests/BugsnagUnity.Tests/ExceptionTests.cs @@ -52,6 +52,28 @@ public void ParseExceptionFromLogMessage() [Test] public void ParseAndroidExceptionFromLogMessage() + { + string condition = "AndroidJavaException: java.lang.IllegalArgumentException"; + string stacktrace = @"java.lang.IllegalArgumentException +com.example.bugsnagcrashplugin.CrashHelper.UnhandledCrash(CrashHelper.java:11) +com.unity3d.player.UnityPlayer.nativeRender(Native Method)"; + var logType = UnityEngine.LogType.Error; + var log = new UnityLogMessage(condition, stacktrace, logType); + var exception = Exception.FromUnityLogMessage(log, new System.Diagnostics.StackFrame[] {}, Severity.Warning); + var stack = exception.StackTrace.ToList(); + Assert.AreEqual("java.lang.IllegalArgumentException", exception.ErrorClass); + Assert.True(System.String.IsNullOrEmpty(exception.ErrorMessage)); + Assert.AreEqual(2, stack.Count); + Assert.AreEqual("com.example.bugsnagcrashplugin.CrashHelper.UnhandledCrash()", stack[0].Method); + Assert.AreEqual("CrashHelper.java", stack[0].File); + Assert.AreEqual(11, stack[0].LineNumber); + Assert.AreEqual("com.unity3d.player.UnityPlayer.nativeRender()", stack[1].Method); + Assert.AreEqual("Native Method", stack[1].File); + Assert.AreEqual(null, stack[1].LineNumber); + } + + [Test] + public void ParseAndroidExceptionAndMessageFromLogMessage() { string condition = "AndroidJavaException: java.lang.ArrayIndexOutOfBoundsException: length=2; index=2"; string stacktrace = @"java.lang.ArrayIndexOutOfBoundsException: length=2; index=2