refactor(errors): унифицировал доменные ошибки и добавил failed-статус задач
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package com.github.nullptroma.wallenc.domain.errors
|
||||
|
||||
/**
|
||||
* Единая иерархия сбоев Wallenc. Ожидаемые бизнес-отказы (CanEncryptResult и т.п.)
|
||||
* остаются отдельными sealed-типами; сюда попадают только операционные ошибки.
|
||||
*/
|
||||
sealed class WallencException(
|
||||
message: String? = null,
|
||||
cause: Throwable? = null,
|
||||
) : Exception(message, cause) {
|
||||
|
||||
sealed class Feature : WallencException() {
|
||||
data object StorageNotFound : Feature()
|
||||
data object NeedsDecryptedView : Feature()
|
||||
data object SecretNotFound : Feature()
|
||||
data object StorageNotWritable : Feature()
|
||||
}
|
||||
|
||||
sealed class Storage(cause: Throwable? = null) : WallencException(cause = cause) {
|
||||
data object NotAvailable : Storage()
|
||||
data object FileNotFound : Storage()
|
||||
data object IncorrectKey : Storage()
|
||||
data class IoFailed(override val cause: Throwable) : Storage(cause)
|
||||
data object EncInfoMissing : Storage()
|
||||
data object NotEncrypted : Storage()
|
||||
data object NotWritable : Storage()
|
||||
data object NotAFile : Storage()
|
||||
data object NotADirectory : Storage()
|
||||
data object PathIsFile : Storage()
|
||||
data object CannotWriteOverDirectory : Storage()
|
||||
data object DeleteRootForbidden : Storage()
|
||||
data object UnexpectedState : Storage()
|
||||
}
|
||||
|
||||
/** Ошибки аутентификации (OAuth, токен), без привязки к провайдеру. */
|
||||
sealed class Auth : WallencException() {
|
||||
data object Failed : Auth()
|
||||
data object TokenMissing : Auth()
|
||||
}
|
||||
|
||||
/** Сетевые и удалённые операции (HTTP, блокировки, таймауты). */
|
||||
sealed class Network(cause: Throwable? = null) : WallencException(cause = cause) {
|
||||
data class HttpFailed(
|
||||
val operation: String,
|
||||
val statusCode: Int,
|
||||
override val cause: Throwable? = null,
|
||||
) : Network(cause)
|
||||
data class IoFailed(override val cause: Throwable) : Network(cause)
|
||||
data object ResourceLocked : Network()
|
||||
data object OperationFailed : Network()
|
||||
data object OperationTimedOut : Network()
|
||||
}
|
||||
|
||||
data class Unknown(override val cause: Throwable?) : WallencException(cause = cause)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.github.nullptroma.wallenc.domain.errors
|
||||
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
||||
fun Throwable.toWallencException(): WallencException = when (this) {
|
||||
is WallencException -> this
|
||||
is FileNotFoundException -> WallencException.Storage.FileNotFound
|
||||
is IOException -> WallencException.Network.IoFailed(this)
|
||||
else -> WallencException.Unknown(this)
|
||||
}
|
||||
|
||||
fun Throwable.rethrowAsWallencException(): Nothing = throw toWallencException()
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.github.nullptroma.wallenc.domain.tasks
|
||||
|
||||
import com.github.nullptroma.wallenc.domain.errors.WallencException
|
||||
|
||||
interface TaskContext {
|
||||
val taskId: TaskId
|
||||
|
||||
@@ -8,4 +10,6 @@ interface TaskContext {
|
||||
suspend fun reportProgress(progress: TaskProgress) = reportProgress(progress.fraction, progress.label)
|
||||
|
||||
fun log(level: TaskLogLevel, message: String)
|
||||
|
||||
fun fail(error: WallencException): Nothing
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.github.nullptroma.wallenc.domain.tasks
|
||||
|
||||
import com.github.nullptroma.wallenc.domain.errors.WallencException
|
||||
|
||||
sealed class TaskRunState {
|
||||
data object Queued : TaskRunState()
|
||||
data class Running(val progress: TaskProgress?) : TaskRunState()
|
||||
data object Completed : TaskRunState()
|
||||
data object Cancelled : TaskRunState()
|
||||
data class Failed(val message: String) : TaskRunState()
|
||||
data class Failed(val error: WallencException) : TaskRunState()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.github.nullptroma.wallenc.domain.errors
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertSame
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
||||
class WallencExceptionMappingTest {
|
||||
|
||||
@Test
|
||||
fun preservesWallencException() {
|
||||
val original = WallencException.Feature.StorageNotFound
|
||||
assertSame(original, original.toWallencException())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapsFileNotFoundException() {
|
||||
val mapped = FileNotFoundException("missing").toWallencException()
|
||||
assertEquals(WallencException.Storage.FileNotFound, mapped)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapsIOExceptionToIoFailed() {
|
||||
val cause = IOException("disk")
|
||||
val mapped = cause.toWallencException()
|
||||
assertTrue(mapped is WallencException.Network.IoFailed)
|
||||
assertSame(cause, (mapped as WallencException.Network.IoFailed).cause)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapsGenericExceptionToUnknown() {
|
||||
val cause = Exception("boom")
|
||||
val mapped = cause.toWallencException()
|
||||
assertTrue(mapped is WallencException.Unknown)
|
||||
assertSame(cause, (mapped as WallencException.Unknown).cause)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user