Merge pull request #7395 from hayaksi1/fix/7393-bug-report-submission

Fix bug reports failing to send after the app has crashed
This commit is contained in:
Benoit Marty
2026-08-13 09:12:44 +02:00
committed by GitHub
3 changed files with 81 additions and 1 deletions
@@ -35,4 +35,11 @@ object RageshakeConfig {
* The maximum number of log lines a rageshake can contain.
*/
const val MAX_LOG_LINES_SIZE = 1_000_000
/**
* The maximum size of the description. The bug report server copies it verbatim into a GitHub issue body,
* which GitHub rejects above 65536 characters. The remaining budget is left to the other reported fields,
* mainly the list of the omitted log file names.
*/
const val MAX_DESCRIPTION_SIZE = 40 * 1024
}
@@ -152,7 +152,7 @@ class DefaultBugReporter(
append("\n\n\n\n--------------------------------- crash call stack ---------------------------------\n")
append(crashCallStack)
}
}
}.truncateDescription()
val gzippedFiles = mutableListOf<File>()
var filesTooBig = emptyList<String>()
@@ -494,4 +494,13 @@ class DefaultBugReporter(
private fun countLogLines(file: File): Int {
return file.reader().useLines { it.count() }
}
private fun String.truncateDescription(): String {
return if (length <= RageshakeConfig.MAX_DESCRIPTION_SIZE) {
this
} else {
take(RageshakeConfig.MAX_DESCRIPTION_SIZE) +
"\n\n--------------------------------- truncated, see the attached logs ---------------------------------"
}
}
}
@@ -309,6 +309,68 @@ class DefaultBugReporterTest : RobolectricTest() {
assertThat(foundValues["label"]).isEqualTo("crash")
}
@Test
fun `test sendBugReport truncates a description which is too long`() = runTest {
val server = MockWebServer()
server.enqueue(
MockResponse()
.setResponseCode(200)
)
server.start()
val hugeCrashCallStack = "a".repeat(RageshakeConfig.MAX_DESCRIPTION_SIZE * 2)
val sut = createDefaultBugReporter(
server = server,
crashDataStore = FakeCrashDataStore(hugeCrashCallStack, true),
)
sut.sendBugReport(
withDevicesLogs = true,
withCrashLogs = true,
withScreenshot = true,
problemDescription = "a bug occurred",
canContact = true,
listener = NoopBugReporterListener(),
)
val request = server.takeRequest()
val text = collectValuesFromFormData(request)["text"]!!
assertThat(text).startsWith("a bug occurred")
assertThat(text).contains("truncated")
assertThat(text.length).isAtMost(RageshakeConfig.MAX_DESCRIPTION_SIZE + TRUNCATION_MARKER_MAX_SIZE)
assertThat(text.length).isLessThan(GITHUB_MAX_ISSUE_BODY_SIZE)
server.shutdown()
}
@Test
fun `test sendBugReport does not truncate a description which fits`() = runTest {
val server = MockWebServer()
server.enqueue(
MockResponse()
.setResponseCode(200)
)
server.start()
val sut = createDefaultBugReporter(
server = server,
crashDataStore = FakeCrashDataStore("I did crash", true),
)
sut.sendBugReport(
withDevicesLogs = true,
withCrashLogs = true,
withScreenshot = true,
problemDescription = "a bug occurred",
canContact = true,
listener = NoopBugReporterListener(),
)
val request = server.takeRequest()
val text = collectValuesFromFormData(request)["text"]!!
assertThat(text).startsWith("a bug occurred")
assertThat(text).endsWith("I did crash")
assertThat(text).doesNotContain("truncated")
server.shutdown()
}
private fun collectValuesFromFormData(request: RecordedRequest): HashMap<String, String> {
val boundary = request.headers["Content-Type"]!!.split("=").last()
val foundValues = HashMap<String, String>()
@@ -535,5 +597,7 @@ class DefaultBugReporterTest : RobolectricTest() {
companion object {
private const val EXPECTED_NUMBER_OF_PROGRESS_VALUE = 18
private const val GITHUB_MAX_ISSUE_BODY_SIZE = 65_536
private const val TRUNCATION_MARKER_MAX_SIZE = 200
}
}