Skip to content

Commit

Permalink
Merge pull request #553 from bugsnag/anr-message-improvements
Browse files Browse the repository at this point in the history
Improve ANR error message information
  • Loading branch information
fractalwrench committed Aug 14, 2019
2 parents 78eeab3 + 2493924 commit 41145c9
Show file tree
Hide file tree
Showing 14 changed files with 444 additions and 127 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
* Migrate dependencies to androidx
[#554](https://github.com/bugsnag/bugsnag-android/pull/554)

* Improve ANR error message information
[#553](https://github.com/bugsnag/bugsnag-android/pull/553)

## 4.18.0-beta01 (2019-08-09)

* Improve ANR error message information
[#553](https://github.com/bugsnag/bugsnag-android/pull/553)

## 4.17.2 (2019-08-01)

### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.bugsnag.android

import com.bugsnag.android.BugsnagTestUtils.generateConfiguration
import com.bugsnag.android.BugsnagTestUtils.streamableToJsonArray
import org.json.JSONArray
import org.json.JSONObject
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class BugsnagExceptionTest {

private val config = generateConfiguration()

@Test
fun stacktraceConstructorSerialisation() {
val trace = arrayOf(StackTraceElement("Foo", "bar", "Foo.kt", 1))
val exc = jsonObjectFromException(BugsnagException("MyClass", "Custom message", trace))
assertEquals("MyClass", exc.get("errorClass"))
assertEquals("Custom message", exc.get("message"))
assertEquals("android", exc.get("type"))

val stacktrace = exc.get("stacktrace") as JSONArray
assertTrue(stacktrace.length() > 0)
}

@Test
fun throwableConstructorSerialisation() {
val exc = jsonObjectFromException(BugsnagException(RuntimeException("oops")))
assertEquals("java.lang.RuntimeException", exc.get("errorClass"))
assertEquals("oops", exc.get("message"))
assertEquals("android", exc.get("type"))

val stacktrace = exc.get("stacktrace") as JSONArray
assertTrue(stacktrace.length() > 0)
}

@Test
fun overrideName() {
val bugsnagException = BugsnagException(RuntimeException("oops"))
bugsnagException.name = "FatalNetworkError"
val exc = jsonObjectFromException(bugsnagException)
assertEquals("FatalNetworkError", exc.get("errorClass"))
}

@Test
fun overrideMessage() {
val bugsnagException = BugsnagException(RuntimeException("oops"))
bugsnagException.setMessage("User not found")
val exc = jsonObjectFromException(bugsnagException)
assertEquals("User not found", exc.get("message"))
}

@Test
fun overrideType() {
val bugsnagException = BugsnagException(RuntimeException("oops"))
bugsnagException.type = "browserjs"
val exc = jsonObjectFromException(bugsnagException)
assertEquals("browserjs", exc.get("type"))
}

@Test
fun nestedBugsnagException() {
val nestedThrowable = BugsnagException(BugsnagException(RuntimeException("oops")))
val exc = jsonObjectFromException(nestedThrowable)
assertEquals("java.lang.RuntimeException", exc.get("errorClass"))
assertEquals("oops", exc.get("message"))
assertEquals("android", exc.get("type"))

val stacktrace = exc.get("stacktrace") as JSONArray
assertTrue(stacktrace.length() > 0)
}

private fun jsonObjectFromException(bugsnagException: BugsnagException): JSONObject {
val exceptions = Exceptions(config, bugsnagException)
val json = streamableToJsonArray(exceptions)
val exc = json.get(0) as JSONObject
return exc
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.bugsnag.android

import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

class ErrorNameTest {

private lateinit var error: Error

@Before
fun setUp() {
val config = Configuration("api-key")
val exception = RuntimeException("Example message", RuntimeException("Another"))
error = Error.Builder(config, exception, null, Thread.currentThread(), false).build()
}

@Test
fun exceptionTypeConverted() {
assertTrue(error.exception is BugsnagException)
assertTrue(error.exceptions.exception is BugsnagException)
assertTrue(error.exceptions.exception.cause is RuntimeException)
}

@Test
fun defaultExceptionName() {
assertEquals("java.lang.RuntimeException", error.exceptionName)
}

@Test
fun defaultExceptionMessage() {
assertEquals("Example message", error.exceptionMessage)
}

@Test
fun overrideExceptionName() {
error.exceptionName = "Foo"
assertEquals("Foo", error.exceptionName)
}

@Test
fun overrideExceptionMessage() {
error.exceptionMessage = "Some custom message"
assertEquals("Some custom message", error.exceptionMessage)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,6 @@ public void testShouldIgnoreClass() {
assertTrue(error.shouldIgnoreClass());
}

@Test
public void testGetExceptionName() {
assertEquals("java.lang.RuntimeException", error.getExceptionName());
}

@Test
public void testGetExceptionMessage() {
assertEquals("Example message", error.getExceptionMessage());
}

@Test
public void testBasicSerialization() throws JSONException, IOException {
error.setAppData(client.getAppData().getAppData());
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.bugsnag.android

import com.bugsnag.android.BugsnagTestUtils.generateConfiguration
import com.bugsnag.android.BugsnagTestUtils.streamableToJsonArray
import org.json.JSONObject
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test

class ExceptionsTest {

private lateinit var config: Configuration

@Before
fun setUp() {
config = generateConfiguration()
}

@Test
fun testBasicException() {
val oops = RuntimeException("oops")
val exceptions = Exceptions(config, BugsnagException(oops))
val exceptionsJson = streamableToJsonArray(exceptions)

assertEquals(1, exceptionsJson.length().toLong())

val firstException = exceptionsJson.get(0) as JSONObject
assertEquals("java.lang.RuntimeException", firstException.get("errorClass"))
assertEquals("oops", firstException.get("message"))
assertNotNull(firstException.get("stacktrace"))
}

@Test
fun testCauseException() {
val ex = RuntimeException("oops", Exception("cause"))
val exceptions = Exceptions(config, BugsnagException(ex))
val exceptionsJson = streamableToJsonArray(exceptions)

assertEquals(2, exceptionsJson.length().toLong())

val firstException = exceptionsJson.get(0) as JSONObject
assertEquals("java.lang.RuntimeException", firstException.get("errorClass"))
assertEquals("oops", firstException.get("message"))
assertNotNull(firstException.get("stacktrace"))

val causeException = exceptionsJson.get(1) as JSONObject
assertEquals("java.lang.Exception", causeException.get("errorClass"))
assertEquals("cause", causeException.get("message"))
assertNotNull(causeException.get("stacktrace"))
}

@Test
fun testNamedException() {
val element = StackTraceElement("Class", "method", "Class.java", 123)
val frames = arrayOf(element)
val error = Error.Builder(
config, "RuntimeException",
"Example message", frames, BugsnagTestUtils.generateSessionTracker(),
Thread.currentThread()
).build()
val exceptions = Exceptions(config, BugsnagException(error.exception))

val exceptionJson = streamableToJsonArray(exceptions).getJSONObject(0)
assertEquals("RuntimeException", exceptionJson.get("errorClass"))
assertEquals("Example message", exceptionJson.get("message"))

val stackframeJson = exceptionJson.getJSONArray("stacktrace").getJSONObject(0)
assertEquals("Class.method", stackframeJson.get("method"))
assertEquals("Class.java", stackframeJson.get("file"))
assertEquals(123, stackframeJson.get("lineNumber"))
}
}
Loading

0 comments on commit 41145c9

Please sign in to comment.