-
-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added handler for crashes: will open a pre-formatted email to report …
…the crash
- Loading branch information
1 parent
5d04c31
commit ea8c4fe
Showing
8 changed files
with
103 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,72 +4,50 @@ import android.content.Intent.ACTION_SENDTO | |
import android.content.Intent.ACTION_VIEW | ||
import android.content.Intent.EXTRA_EMAIL | ||
import android.content.Intent.EXTRA_SUBJECT | ||
import android.content.Intent.EXTRA_TEXT | ||
import android.net.Uri | ||
import android.os.Build | ||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import androidx.test.filters.MediumTest | ||
import com.nononsenseapps.feeder.BuildConfig | ||
import org.junit.Assert.assertEquals | ||
import kotlin.test.assertEquals | ||
import kotlin.test.assertTrue | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
@MediumTest | ||
class BugReportKTest { | ||
@Test | ||
fun bodyContainsAndroidInformation() { | ||
assertEquals( | ||
""" | ||
${BuildConfig.APPLICATION_ID} (flavor ${BuildConfig.BUILD_TYPE.ifBlank { "None" }}) | ||
version ${BuildConfig.VERSION_NAME} (code ${BuildConfig.VERSION_CODE}) | ||
on Android ${Build.VERSION.RELEASE} (SDK-${Build.VERSION.SDK_INT}) | ||
on a Tablet? No | ||
Describe your issue and how to reproduce it below: | ||
""".trimIndent(), | ||
emailBody(false), | ||
) | ||
} | ||
|
||
@Test | ||
fun bodyContainsAndroidInformationAsTablet() { | ||
assertEquals( | ||
""" | ||
${BuildConfig.APPLICATION_ID} (flavor ${BuildConfig.BUILD_TYPE.ifBlank { "None" }}) | ||
version ${BuildConfig.VERSION_NAME} (code ${BuildConfig.VERSION_CODE}) | ||
on Android ${Build.VERSION.RELEASE} (SDK-${Build.VERSION.SDK_INT}) | ||
on a Tablet? Yes | ||
Describe your issue and how to reproduce it below: | ||
""".trimIndent(), | ||
emailBody(true), | ||
) | ||
} | ||
fun bugIntentIsCorrect() { | ||
val intent = emailBugReportIntent() | ||
|
||
@Test | ||
fun subjectIsSensible() { | ||
assertEquals( | ||
"Bug report for Feeder", | ||
emailSubject(), | ||
) | ||
} | ||
assertEquals(ACTION_SENDTO, intent.action) | ||
assertEquals(Uri.parse("mailto:[email protected]"), intent.data) | ||
assertEquals("Bug report for Feeder", intent.getStringExtra(EXTRA_SUBJECT)) | ||
assertEquals("[email protected]", intent.getStringExtra(EXTRA_EMAIL)) | ||
|
||
@Test | ||
fun emailAddressIsCorrect() { | ||
assertEquals( | ||
"[email protected]", | ||
emailReportAddress(), | ||
) | ||
assertTrue(intent.getStringExtra(EXTRA_TEXT)) { | ||
"Application: " in intent.getStringExtra(EXTRA_TEXT)!! | ||
} | ||
} | ||
|
||
@Test | ||
fun emailIntentIsCorrect() { | ||
val intent = emailBugReportIntent() | ||
|
||
assertEquals(ACTION_SENDTO, intent.action) | ||
assertEquals(Uri.parse("mailto:${emailReportAddress()}"), intent.data) | ||
assertEquals(emailSubject(), intent.getStringExtra(EXTRA_SUBJECT)) | ||
assertEquals(emailReportAddress(), intent.getStringExtra(EXTRA_EMAIL)) | ||
fun crashIntentIsCorrect() { | ||
try { | ||
@Suppress("DIVISION_BY_ZERO") | ||
1 / 0 | ||
} catch (e: Exception) { | ||
val intent = emailCrashReportIntent(e) | ||
|
||
assertEquals(ACTION_SENDTO, intent.action) | ||
assertEquals(Uri.parse("mailto:[email protected]"), intent.data) | ||
assertEquals("Crash report for Feeder", intent.getStringExtra(EXTRA_SUBJECT)) | ||
assertEquals("[email protected]", intent.getStringExtra(EXTRA_EMAIL)) | ||
|
||
assertTrue(intent.getStringExtra(EXTRA_TEXT)) { | ||
"java.lang.ArithmeticException: divide by zero" in intent.getStringExtra(EXTRA_TEXT)!! | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
|
28 changes: 28 additions & 0 deletions
28
app/src/main/java/com/nononsenseapps/feeder/ui/ActivityExceptionHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.nononsenseapps.feeder.ui | ||
|
||
import android.app.Activity | ||
import android.content.Intent | ||
import android.util.Log | ||
import com.nononsenseapps.feeder.util.emailCrashReportIntent | ||
import kotlin.system.exitProcess | ||
|
||
fun Activity.installExceptionHandler() { | ||
val mainHandler = Thread.getDefaultUncaughtExceptionHandler() | ||
Thread.setDefaultUncaughtExceptionHandler { thread, throwable -> | ||
try { | ||
Log.w("FEEDER_PANIC", "Trying to report unhandled exception", throwable) | ||
val intent = emailCrashReportIntent(throwable) | ||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | ||
startActivity(intent) | ||
} catch (e: Exception) { | ||
e.printStackTrace() | ||
} finally { | ||
// Necessary to handle the error or the process will freeze | ||
if (mainHandler != null) { | ||
mainHandler.uncaughtException(thread, throwable) | ||
} else { | ||
exitProcess(1) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,30 +9,48 @@ import android.net.Uri | |
import android.os.Build | ||
import com.nononsenseapps.feeder.BuildConfig | ||
|
||
internal fun emailSubject(): String = "Bug report for Feeder" | ||
private fun deviceInfoBlock(): String = """ | ||
Application: ${BuildConfig.APPLICATION_ID} (flavor ${BuildConfig.BUILD_TYPE.ifBlank { "None" }}) | ||
Version: ${BuildConfig.VERSION_NAME} (code ${BuildConfig.VERSION_CODE}) | ||
Android: ${Build.VERSION.RELEASE} (SDK ${Build.VERSION.SDK_INT}) | ||
Device: ${Build.MANUFACTURER} ${Build.MODEL} | ||
""".trimIndent() | ||
|
||
internal fun emailBody(isTablet: Boolean): String = | ||
private fun bugBody(): String = | ||
""" | ||
${BuildConfig.APPLICATION_ID} (flavor ${BuildConfig.BUILD_TYPE.ifBlank { "None" }}) | ||
version ${BuildConfig.VERSION_NAME} (code ${BuildConfig.VERSION_CODE}) | ||
on Android ${Build.VERSION.RELEASE} (SDK-${Build.VERSION.SDK_INT}) | ||
on a Tablet? ${ | ||
if (isTablet) { | ||
"Yes" | ||
} else { | ||
"No" | ||
} | ||
} | ||
Describe your issue and how to reproduce it below: | ||
${deviceInfoBlock()} | ||
Hello. | ||
I'd like to report an issue: | ||
""".trimIndent() | ||
|
||
internal fun emailReportAddress(): String = "[email protected]" | ||
private const val emailReportAddress: String = "[email protected]" | ||
|
||
fun emailBugReportIntent(): Intent = Intent(ACTION_SENDTO).also { | ||
it.putExtra(EXTRA_SUBJECT, emailSubject()) | ||
it.putExtra(EXTRA_EMAIL, emailReportAddress()) | ||
it.data = Uri.parse("mailto:${emailReportAddress()}") | ||
fun emailBugReportIntent(): Intent = Intent(ACTION_SENDTO).apply { | ||
data = Uri.parse("mailto:$emailReportAddress") | ||
putExtra(EXTRA_SUBJECT, "Bug report for Feeder") | ||
putExtra(EXTRA_EMAIL, emailReportAddress) | ||
putExtra(Intent.EXTRA_TEXT, bugBody()) | ||
} | ||
|
||
private const val crashReportAddress: String = "[email protected]" | ||
|
||
private fun crashBody(throwable: Throwable): String = | ||
""" | ||
${deviceInfoBlock()} | ||
Unhandled exception: | ||
${throwable.stackTraceToString()} | ||
""".trimIndent() | ||
|
||
fun emailCrashReportIntent(throwable: Throwable): Intent = Intent(ACTION_SENDTO).apply { | ||
data = Uri.parse("mailto:$crashReportAddress") | ||
putExtra(EXTRA_SUBJECT, "Crash report for Feeder") | ||
putExtra(EXTRA_EMAIL, crashReportAddress) | ||
putExtra(Intent.EXTRA_TEXT, crashBody(throwable)) | ||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) | ||
} | ||
|
||
fun openGitlabIssues(): Intent = Intent(ACTION_VIEW).also { | ||
|