diff --git a/lib/src/main/kotlin/io/nexure/capsule/Capsule.kt b/lib/src/main/kotlin/io/nexure/capsule/Capsule.kt index 5bf568b..fd9beee 100644 --- a/lib/src/main/kotlin/io/nexure/capsule/Capsule.kt +++ b/lib/src/main/kotlin/io/nexure/capsule/Capsule.kt @@ -83,7 +83,13 @@ private constructor( ): Comparable { private val instance: LazyValue = LazyValue(constructor) - fun getInstance(): Any = instance() + fun getInstance(): Any { + return try { + instance() + } catch (e: Exception) { + throw DependencyException(key, e) + } + } override fun toString(): String = key @@ -99,12 +105,11 @@ private constructor( private fun classKey(clazz: Class<*>): String = clazz.canonicalName ?: clazz.descriptorString() internal class DependencyException( - val clazz: Class<*>, - override val cause: DependencyException? = null + val key: String, + override val cause: Exception? = null ) : Exception() { - override val message: String = if (cause != null) { - "Unable to provide dependency for class $clazz: \n\t${cause.message}" - } else { - "Unable to provide dependency for class $clazz" - } + constructor(clazz: Class<*>, cause: Exception? = null) : this(classKey(clazz), cause) + + override val message: String = "Unable to provide dependency for class ${rootKey()}" + fun rootKey(): String = if (this.cause is DependencyException) this.cause.key else this.key } diff --git a/lib/src/test/kotlin/io/nexure/capsule/CapsuleTest.kt b/lib/src/test/kotlin/io/nexure/capsule/CapsuleTest.kt index ccc259d..98daee7 100644 --- a/lib/src/test/kotlin/io/nexure/capsule/CapsuleTest.kt +++ b/lib/src/test/kotlin/io/nexure/capsule/CapsuleTest.kt @@ -3,6 +3,7 @@ package io.nexure.capsule import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertNull +import kotlin.test.assertTrue class CapsuleTest { @Test @@ -162,7 +163,6 @@ class CapsuleTest { assertEquals(listOf("3", "2", "1"), third.getMany().map { it.hello() }) } - @Test fun `test only needed dependency in created on call to get()`() { val parent = Capsule { @@ -182,6 +182,25 @@ class CapsuleTest { val greeter: Greeter = child.get() assertEquals("foo", greeter.hello()) } + + @Test + fun `DependencyException should provide context on which class creation that failed`() { + class ComplexGreeter( + val string: String, + val double: Double + ) : Greeter { + override fun hello(): String = "foo" + } + + val capsule = Capsule {} + try { + val g = capsule.get() + assertTrue(false) + } catch (e: DependencyException) { + assertEquals("double", e.rootKey()) + assertEquals("Unable to provide dependency for class double", e.message) + } + } } interface Greeter {