diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 79244257c..3c2192a0c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ jooq = "3.18.25" kotlin = "2.0.21" kotlinxCoroutines = "1.10.1" ktlint = "0.47.1" -misk = "2025.04.04.132805-43bcba0" +misk = "2025.04.09.202256-90dc722" okhttp = "5.0.0-alpha.14" sqldelight = "2.0.2" wire = "5.2.1" diff --git a/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillCreateHandlerAction.kt b/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillCreateHandlerAction.kt index b67355267..8f176be06 100644 --- a/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillCreateHandlerAction.kt +++ b/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillCreateHandlerAction.kt @@ -71,7 +71,7 @@ class BackfillCreateHandlerAction @Inject constructor( val errorHtmlResponseBody = dashboardPageLayout.newBuilder() .buildHtmlResponseBody { div("py-20") { - AlertError(message = "Backfill Create Failed: $e", label = "Try Again", onClick = "history.back(); return false;") + AlertError(message = "Backfill create or clone failed: $e", label = "Try Again", onClick = "history.back(); return false;") } } return Response( diff --git a/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillShowButtonHandlerAction.kt b/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillShowButtonHandlerAction.kt index 3126a42a9..d8a62f142 100644 --- a/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillShowButtonHandlerAction.kt +++ b/service/src/main/kotlin/app/cash/backfila/ui/actions/BackfillShowButtonHandlerAction.kt @@ -7,8 +7,9 @@ import app.cash.backfila.dashboard.StopBackfillRequest import app.cash.backfila.dashboard.UpdateBackfillAction import app.cash.backfila.dashboard.UpdateBackfillRequest import app.cash.backfila.service.persistence.BackfillState -import javax.inject.Inject -import javax.inject.Singleton +import app.cash.backfila.ui.components.AlertError +import app.cash.backfila.ui.components.DashboardPageLayout +import kotlinx.html.div import misk.security.authz.Authenticated import misk.web.Get import misk.web.PathParam @@ -20,9 +21,12 @@ import misk.web.actions.WebAction import misk.web.mediatype.MediaTypes import misk.web.toResponseBody import okhttp3.Headers +import javax.inject.Inject +import javax.inject.Singleton @Singleton class BackfillShowButtonHandlerAction @Inject constructor( + private val dashboardPageLayout: DashboardPageLayout, private val startBackfillAction: StartBackfillAction, private val stopBackfillAction: StopBackfillAction, private val updateBackfillAction: UpdateBackfillAction, @@ -35,43 +39,63 @@ class BackfillShowButtonHandlerAction @Inject constructor( @QueryParam field_id: String?, @QueryParam field_value: String?, ): Response { - if (!field_id.isNullOrBlank()) { - when (field_id) { - "state" -> { - if (field_value == BackfillState.PAUSED.name) { - stopBackfillAction.stop(id.toLong(), StopBackfillRequest()) - } else if (field_value == BackfillState.RUNNING.name) { - startBackfillAction.start(id.toLong(), StartBackfillRequest()) + try { + if (!field_id.isNullOrBlank()) { + when (field_id) { + "state" -> { + if (field_value == BackfillState.PAUSED.name) { + stopBackfillAction.stop(id.toLong(), StopBackfillRequest()) + } else if (field_value == BackfillState.RUNNING.name) { + startBackfillAction.start(id.toLong(), StartBackfillRequest()) + } } - } - "num_threads" -> { - val numThreads = field_value?.toIntOrNull() - if (numThreads != null) { - updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(num_threads = numThreads)) + + "num_threads" -> { + val numThreads = field_value?.toIntOrNull() + if (numThreads != null) { + updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(num_threads = numThreads)) + } } - } - "scan_size" -> { - val scanSize = field_value?.toLongOrNull() - if (scanSize != null) { - updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(scan_size = scanSize)) + + "scan_size" -> { + val scanSize = field_value?.toLongOrNull() + if (scanSize != null) { + updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(scan_size = scanSize)) + } } - } - "batch_size" -> { - val batchSize = field_value?.toLongOrNull() - if (batchSize != null) { - updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(batch_size = batchSize)) + + "batch_size" -> { + val batchSize = field_value?.toLongOrNull() + if (batchSize != null) { + updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(batch_size = batchSize)) + } } - } - "extra_sleep_ms" -> { - val extraSleepMs = field_value?.toLongOrNull() - if (extraSleepMs != null) { - updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(extra_sleep_ms = extraSleepMs)) + + "extra_sleep_ms" -> { + val extraSleepMs = field_value?.toLongOrNull() + if (extraSleepMs != null) { + updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(extra_sleep_ms = extraSleepMs)) + } + } + + "backoff_schedule" -> { + updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(backoff_schedule = field_value)) } - } - "backoff_schedule" -> { - updateBackfillAction.update(id.toLong(), UpdateBackfillRequest(backoff_schedule = field_value)) } } + } catch (e: Exception) { + // Since this action is only hit from the UI, catch any validation errors and show them to the user + val errorHtmlResponseBody = dashboardPageLayout.newBuilder() + .buildHtmlResponseBody { + div("py-20") { + AlertError(message = "Update backfill field failed: $e", label = "Try Again", onClick = "history.back(); return false;") + } + } + return Response( + body = errorHtmlResponseBody, + statusCode = 200, + headers = Headers.headersOf("Content-Type", MediaTypes.TEXT_HTML), + ) } return Response(