DEV Community

Cover image for From PHP to Kotlin - Day 3 - Dealing with exceptions
Fernando Aparicio
Fernando Aparicio

Posted on

From PHP to Kotlin - Day 3 - Dealing with exceptions

Previously, our Value object validated that the value was correct. But we used a generic exception, which only lets us put a message.

That may be fine, but in DDD context it's not quite right. The idea is that through folder struture and files that we have, we can get an idea of the domain.

In this case, it's more wise to handle a custom exception. And in the future, we will be able to better control the exceptions in our flow.

So, we're going to change the test that expects the exception and we're going to be more explicit.

...
internal class YMowerPositionTest
{
...
    @Test
    fun `Should throw exception for invalid values` ()
    {
        assertThrows(InvalidMowerPositionException::class.java) {
            YMowerPosition.build(INVALID_POSITION)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And to create the exception, we'll use a test for the
InvalidMowerPositionException.

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.*
import kotlin.test.Test

private const val POSITION: Int = 4;
private const val MESSAGE: String = "Invalid Y position $POSITION. Only positive values are valid."

internal class InvalidMowerPositionExceptionTest
{
    @Test
    fun `Should be build with custom value`() {
        val exception = assertThrows(InvalidMowerPositionException::class.java) {
            throw InvalidMowerPositionException.withValue(POSITION)
        }

        assertThat(exception.message).isEqualTo(MESSAGE)
    }
}
Enter fullscreen mode Exit fullscreen mode

And the code that implements it.

class InvalidMowerPositionException private constructor (message: String? = null, cause: Throwable? = null) : Exception(message, cause) {
    companion object {
        private const val MESSAGE: String = "Invalid Y position %d. Only positive values are valid."

        @JvmStatic
        fun withValue(value: Int): InvalidMowerPositionException
        {
            return InvalidMowerPositionException(String.format(MESSAGE, value), null)
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This time we've gone faster creating that class. We know a little better how to do it and it's not more complex.

Tip

If you take a closer look, when creating the message, the test uses a simple concatenation, and the exception a String.format(). This is done on purpose to avoid do copy/pasting from test to implementation. This ensures that the result is as expected.


Links and resources

Exceptions

https://kotlinlang.org/docs/exceptions.html?q=con#exception-classes


Discussion (0)