Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.itsaky.androidide.assets

class MissingAssetsEntryException(cause: Throwable) : Exception(cause)
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,19 @@ object AssetsInstallationHelper {
}

if (result.isFailure) {
val e = result.exceptionOrNull()
if (e is CancellationException) {
throw e
val e = result.exceptionOrNull() ?: RuntimeException(context.getString(R.string.error_installation_failed))
if (e is CancellationException) throw e

val isMissingAsset = generateSequence(e) { it.cause }.any { it is FileNotFoundException }
val cause = if (isMissingAsset) MissingAssetsEntryException(e) else e
val msg = if (isMissingAsset) {
context.getString(R.string.err_missing_or_corrupt_assets, context.getString(R.string.app_name))
} else {
e.message ?: context.getString(R.string.error_installation_failed)
}
val msg = e?.message ?: "Failed to install assets"
logger.error("Failed to install assets", e)
onProgress(Progress(msg))
return@withContext Result.Failure(e, errorMessage = msg)
return@withContext Result.Failure(cause, errorMessage = msg, shouldReportToSentry = !isMissingAsset)
}

return@withContext Result.Success
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.itsaky.androidide.assets

import android.content.Context
import com.itsaky.androidide.assets.AssetsInstallationHelper.Result.Failure
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkObject
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import java.io.FileNotFoundException

class AssetsInstallationHelperTest {

private val ctx: Context = mockk(relaxed = true)

@Before
fun setup() {
mockkObject(AssetsInstallationHelper)
}

@Test
fun `install with missing asset skips sentry`() = runBlocking {
val helper = AssetsInstallationHelper

every {
helper["checkStorageAccessibility"](any<Context>(), any<AssetsInstallerProgressConsumer>())
} returns null

coEvery {
helper["doInstall"](any<Context>(), any<AssetsInstallerProgressConsumer>())
} throws FileNotFoundException("data/common/gradle.zip.br")

val result = helper.install(ctx)

assertTrue("Expected Result.Failure", result is Failure)
val failure = result as Failure
assertFalse("Should skip Sentry report", failure.shouldReportToSentry)
assertTrue(
"Expected MissingAssetsEntryException as cause",
failure.cause is MissingAssetsEntryException
)
assertTrue(
"Expected FileNotFoundException as root cause",
(failure.cause?.cause) is FileNotFoundException
)
}
}
2 changes: 2 additions & 0 deletions resources/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@
<string name="msg_no_references">No references found</string>
<string name="view_diags">Diagnostics</string>
<string name="title_installation_failed">Installation failed</string>
<string name="error_installation_failed">Failed to install assets</string>
<string name="err_asset_entry_not_found">Entry \'%1$s\' not found in assets zip file</string>
<string name="err_missing_or_corrupt_assets">Missing installation files. %1$s installation might be corrupt or incomplete.</string>
<string name="msg_picked_isnt_dir">The picked file is not a directory.</string>
<string name="please_wait">Please wait for a moment.</string>
<string name="not_enough_storage">Not enough storage available for installation. An additional %1$.1fGB is required on the internal storage partition. You currently have %2$.1fGB available.</string>
Expand Down