diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriter.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriter.kt index a5448ea4d3a22c5810a7b6aaf30da1155321c5a6..992f86be6ca9818e85c56c32d437a08a22ca0f81 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriter.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriter.kt @@ -1,12 +1,17 @@ package de.rki.coronawarnapp.bugreporting.debuglog.internal +import android.annotation.SuppressLint +import android.util.Log import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import timber.log.Timber import java.io.File +import java.io.FileNotFoundException import javax.inject.Inject +@Suppress("BlockingMethodInNonBlockingContext") +@SuppressLint("LogNotTimber") class LogWriter @Inject constructor(val logFile: File) { private var ioLimiter = 0 private val mutex = Mutex() @@ -34,7 +39,28 @@ class LogWriter @Inject constructor(val logFile: File) { } suspend fun write(formattedLine: String): Unit = mutex.withLock { - logFile.appendText(formattedLine + "\n", Charsets.UTF_8) + val performWrite = { + logFile.appendText(formattedLine + "\n", Charsets.UTF_8) + } + + try { + performWrite() + } catch (e: FileNotFoundException) { + Log.e(TAG, "Log file didn't exist when we tried to write, retry.") + + try { + logFile.parentFile?.mkdirs() + logFile.createNewFile() + logFile.writeText("Logfile was deleted.\n") + + performWrite() + + updateLogSize() + } catch (e: Exception) { + Log.e(TAG, "LogWrite retry failed, something is just wrong...", e) + return@withLock + } + } if (ioLimiter % 10 == 0) { updateLogSize() @@ -42,4 +68,8 @@ class LogWriter @Inject constructor(val logFile: File) { } ioLimiter++ } + + companion object { + private const val TAG = "LogWriter" + } } diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriterTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriterTest.kt index 19120d55091bae4e73d55d7e2bd18270d5a9540f..6c261a2c172e6e9ae32a5758df62078899db4079 100644 --- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriterTest.kt +++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/bugreporting/debuglog/internal/LogWriterTest.kt @@ -45,4 +45,27 @@ class LogWriterTest : BaseIOTest() { logSize.value shouldBe 0L } } + + /** + * e.g. System cache cleaning interferring + */ + @Test + fun `if the file is deleted after setup we try to recreate it and do not crash`() = runBlockingTest { + createInstance().apply { + setup() + write("ABC") + logFile.readText() shouldBe "ABC\n" + + logSize.value shouldBe 4L + + logFile.delete() + logFile.parentFile!!.delete() + logFile.exists() shouldBe false + + write("DEF") + logFile.readText() shouldBe "Logfile was deleted.\nDEF\n" + + logSize.value shouldBe 25L + } + } }