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
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ allprojects {
}
}

version = "0.0.3"
version = "0.0.4"
group = "io.github.ustudiocompany"

configurations.all {
Expand Down
2 changes: 2 additions & 0 deletions library/failure/api/failure-library.api
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,14 @@ public final class io/github/ustudiocompany/uframework/failure/FailureKt {
public abstract interface class io/github/ustudiocompany/uframework/failure/TypeFailure : io/github/ustudiocompany/uframework/failure/Failure {
public static final field ACTUAL_VALUE_DETAIL_KEY Ljava/lang/String;
public static final field Companion Lio/github/ustudiocompany/uframework/failure/TypeFailure$Companion;
public static final field EXCEPTION_STACKTRACE Ljava/lang/String;
public static final field PATTERN_DETAIL_KEY Ljava/lang/String;
public abstract fun getType-uX7CcE4 ()Ljava/lang/Class;
}

public final class io/github/ustudiocompany/uframework/failure/TypeFailure$Companion {
public static final field ACTUAL_VALUE_DETAIL_KEY Ljava/lang/String;
public static final field EXCEPTION_STACKTRACE Ljava/lang/String;
public static final field PATTERN_DETAIL_KEY Ljava/lang/String;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.ustudiocompany.uframework.failure

import io.github.ustudiocompany.uframework.failure.Failure.Cause
import io.github.ustudiocompany.uframework.failure.Failure.Details
import io.github.ustudiocompany.uframework.failure.TypeFailure.Companion.EXCEPTION_STACKTRACE

public interface Failure {
/**
Expand Down Expand Up @@ -122,13 +123,16 @@ public fun Failure.fullCode(delimiter: String = "."): String =
}.toString()

/**
* Returns all details of the failure and its causes.
* Returns all details of the failure, its causes, and root exception details if it exists.
* @return the all details.
*/
public fun Failure.allDetails(): Details {
val allDetails = fold(initial = { mutableListOf<Details.Item>().apply { addAll(it.details) } }) { acc, failure ->
acc.apply { addAll(failure.details) }
}
val exception = root().exceptionOrNull()
if (exception != null)
allDetails.add(Details.Item(key = EXCEPTION_STACKTRACE, value = exception.stackTraceToString()))
return if (allDetails.isEmpty())
Details.NONE
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ public interface TypeFailure<T> : Failure {
public companion object {
public const val ACTUAL_VALUE_DETAIL_KEY: String = "actual-value"
public const val PATTERN_DETAIL_KEY: String = "pattern"
public const val EXCEPTION_STACKTRACE: String = "exception-stackTrace"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.ustudiocompany.uframework.failure

import io.github.ustudiocompany.uframework.failure.Failure.Cause
import io.github.ustudiocompany.uframework.failure.Failure.Details
import io.github.ustudiocompany.uframework.failure.TypeFailure.Companion.EXCEPTION_STACKTRACE
import io.github.ustudiocompany.uframework.test.kotest.UnitTest
import io.kotest.datatest.withData
import io.kotest.matchers.collections.shouldContainOnly
Expand All @@ -14,38 +15,52 @@ internal class AllDetailsFailureTest : UnitTest() {
withData(
nameFn = { (failure, _) -> failure.toString() },
listOf(
failure(code = CODE_1) to Details.NONE,
failure(code = CODE_1, details = Details.of(KEY_1 to VALUE_1)) to Details.of(KEY_1 to VALUE_1),
failure(code = CODE_2, cause = failure(code = CODE_1)) to Details.NONE,
failure(
failureRoot(code = CODE_1) to
Details.NONE,
failureRootException(details = Details.of(KEY_1 to VALUE_1)) to
Details.of(
KEY_1 to VALUE_1,
EXCEPTION_STACKTRACE to VALUE_4
),
failureChild(code = CODE_2, cause = failureRoot(code = CODE_1)) to
Details.NONE,
failureChild(
code = CODE_2,
cause = failure(CODE_1),
cause = failureRoot(CODE_1),
details = Details.of(KEY_1 to VALUE_1)
) to Details.of(KEY_1 to VALUE_1),
failure(
) to
Details.of(KEY_1 to VALUE_1),
failureChild(
code = CODE_2,
cause = failure(
cause = failureRoot(
code = CODE_1,
details = Details.of(KEY_1 to VALUE_1)
)
) to Details.of(KEY_1 to VALUE_1),
failure(
) to
Details.of(KEY_1 to VALUE_1),
failureChild(
code = CODE_2,
cause = failure(
cause = failureRoot(
code = CODE_1,
details = Details.of(KEY_1 to VALUE_1)
),
details = Details.of(KEY_2 to VALUE_2)
) to Details.of(KEY_1 to VALUE_1, KEY_2 to VALUE_2)
) to
Details.of(KEY_1 to VALUE_1, KEY_2 to VALUE_2)
)
) { (failure, expected) ->
failure.allDetails() shouldContainOnly expected
}
}
}

private fun failure(code: String, details: Details = Details.NONE): Failure = Root(code = code, details = details)
private fun failure(code: String, cause: Failure, details: Details = Details.NONE): Failure =
private fun failureRoot(code: String, details: Details = Details.NONE): Failure =
Root(code = code, details = details)

private fun failureRootException(code: String = CODE_1, details: Details = Details.NONE): Failure =
RootException(code = code, details = details)

private fun failureChild(code: String, cause: Failure, details: Details = Details.NONE): Failure =
Child(code = code, cause = Cause.Failure(cause), details = details)

private companion object {
Expand All @@ -56,11 +71,20 @@ internal class AllDetailsFailureTest : UnitTest() {
private const val KEY_2 = "key-2"
private const val VALUE_1 = "value-1"
private const val VALUE_2 = "value-2"
private const val VALUE_3 = "value-3"
private val testException = Exception(VALUE_3)
private val VALUE_4 = testException.stackTraceToString()
}

private data class Root(
override val code: String,
override val details: Details = Details.NONE
override val details: Details = Details.NONE,
) : Failure

private data class RootException(
override val code: String,
override val details: Details = Details.NONE,
override val cause: Cause = Cause.Exception(testException)
) : Failure

private data class Child(
Expand Down
Loading