Skip to content

Commit

Permalink
Implement better error handling for export action
Browse files Browse the repository at this point in the history
  • Loading branch information
juraj-hrivnak committed Feb 2, 2025
1 parent fb39d69 commit f43ba96
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,20 +123,34 @@ data class NotRedistributable(val project: Project) : ActionError()
data class CouldNotExport(val profile: ExportProfile, val modpackFileName: String, val reason: String?) : ActionError()
{
override val rawMessage = "Profile ${profile.name} ('$modpackFileName') could not be exported. $reason"
override fun message(arg: String): String = "(${dim(modpackFileName)}) could not be exported. $reason"
override val severity = ErrorSeverity.FATAL
}

data class ErrorWhileExporting(
val profile: ExportProfile, val modpackFileName: String, val underlyingError: ActionError
) : ActionError()
data class IOExportingError(val underlyingError: ActionError) : ActionError()
{
override val rawMessage = message(
"There was an error while exporting profile ${profile.name} ('$modpackFileName'). ",
"There was an file IO error while exporting. ",
underlyingError.rawMessage
)

override fun message(arg: String): String = message(
"There was an error while exporting profile ${profile.name} ('$modpackFileName'). ",
"There was an file IO error while exporting. ",
underlyingError.message()
)

override val severity = underlyingError.severity
}

data class ExportingError(val underlyingError: ActionError) : ActionError()
{
override val rawMessage = message(
"There was an error while exporting. ",
underlyingError.rawMessage
)

override fun message(arg: String): String = message(
"There was an error while exporting. ",
underlyingError.message()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,21 @@ suspend fun ExportProfile.export(
val inputDirectory = Path(cacheDir.pathString, this.name)

val results: List<RuleResult> = this.rules.filterNotNull().produceRuleResults(
onError = { error -> onError(this, ErrorWhileExporting(this, modpackFileName, error)) },
onError = { error -> onError(this, ExportingError(error)) },
lockFile, configFile, this.name, overrides, serverOverrides, clientOverrides
)

// Run export rules
val cachedPaths: List<Path> = results
.resolveResults { error ->
onError(this, ErrorWhileExporting(this, modpackFileName, error))
onError(this, error)
}
.awaitAll()
.filterNotNull()
.plus(
results
.finishResults { error ->
onError(this, ErrorWhileExporting(this, modpackFileName, error))
onError(this, error)
}
.awaitAll()
.filterNotNull()
Expand All @@ -138,7 +138,7 @@ suspend fun ExportProfile.export(
.mapNotNull { file ->
file.tryToResult { it.readBytes() }
.onFailure { error ->
onError(this, ErrorWhileExporting(this, modpackFileName, error))
onError(this, IOExportingError(error))
}
.get()?.let { file to it }
}
Expand All @@ -149,7 +149,7 @@ suspend fun ExportProfile.export(
.mapNotNull { directory ->
directory.tryToResult { it.toFile().walkTopDown() }
.onFailure { error ->
onError(this, ErrorWhileExporting(this, modpackFileName, error))
onError(this, IOExportingError(error))
}.get()
}
.flatMap {
Expand All @@ -164,7 +164,7 @@ suspend fun ExportProfile.export(

val fileTreeWalk = inputDirectory.tryToResult { it.toFile().walkBottomUp() }
.onFailure {error ->
onError(this, ErrorWhileExporting(this, modpackFileName, error))
onError(this, IOExportingError(error))
}.get()

if (fileTreeWalk != null)
Expand All @@ -178,7 +178,7 @@ suspend fun ExportProfile.export(
{
val currentDirFiles = path.tryToResult { it.toFile().listFiles() }
.onFailure { error ->
onError(this, ErrorWhileExporting(this, modpackFileName, error))
onError(this, IOExportingError(error))
}.get()?.mapNotNull { it.toPath() } ?: continue

if (currentDirFiles.isNotEmpty()) continue
Expand Down Expand Up @@ -260,7 +260,7 @@ suspend fun List<RuleResult>.resolveResults(
val action = measureTimedValue {
async {
packagingAction.action()?.let {
onError(it)
onError(ExportingError(it))
}
}
}
Expand All @@ -280,7 +280,7 @@ suspend fun List<RuleResult>.resolveResults(
val action = measureTimedValue {
async(Dispatchers.IO) {
packagingAction.action().let { (file, error) ->
if (error != null) onError(error)
if (error != null) onError(IOExportingError(error))
file
}
}
Expand Down Expand Up @@ -309,7 +309,7 @@ suspend fun List<RuleResult>.finishResults(
val action = measureTimedValue {
async {
ruleResult.packaging.action()?.let {
onError(it)
onError(ExportingError(it))
}
}
}
Expand All @@ -325,7 +325,7 @@ suspend fun List<RuleResult>.finishResults(
val action = measureTimedValue {
async(Dispatchers.IO) {
ruleResult.packaging.action().let { (file, error) ->
if (error != null) onError(error)
if (error != null) onError(IOExportingError(error))
file
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Export.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package teksturepako.pakku.cli.cmd
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.Context
import com.github.ajalt.clikt.core.terminal
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.help
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.mordant.animation.coroutines.animateInCoroutine
import com.github.ajalt.mordant.terminal.danger
import com.github.ajalt.mordant.widgets.Spinner
Expand All @@ -12,7 +15,7 @@ import com.github.michaelbull.result.getOrElse
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import teksturepako.pakku.api.actions.errors.ErrorWhileExporting
import teksturepako.pakku.api.actions.errors.IOExportingError
import teksturepako.pakku.api.actions.export.exportDefaultProfiles
import teksturepako.pakku.api.data.ConfigFile
import teksturepako.pakku.api.data.LockFile
Expand All @@ -27,6 +30,10 @@ class Export : CliktCommand()
{
override fun help(context: Context) = "Export modpack"

private val showIOErrors: Boolean by option("--show-io-errors")
.help("Show file IO error on exporting. (These can be ignored most of the time.)")
.flag()

override fun run(): Unit = runBlocking {
val lockFile = LockFile.readToResult().getOrElse {
terminal.danger(it.message)
Expand Down Expand Up @@ -54,7 +61,7 @@ class Export : CliktCommand()

exportDefaultProfiles(
onError = { profile, error ->
if (error !is ErrorWhileExporting)
if (showIOErrors || error !is IOExportingError)
{
terminal.pError(error, prepend = "[${profile.name} profile]")
}
Expand Down

0 comments on commit f43ba96

Please sign in to comment.