Ozzini
Ozzini

Reputation: 145

Kotlin Try&Catch Exception

I am a very beginner Kotlin programmer. What I'm doing wrong with try & catch code? Is there a problem with the try part or catch part?

fun sumOfDigits(quantity: Int): Int {
    var score = 0
    var digit: Int
    var number: Int = quantity

    if (number < 0) throw ArithmeticException("Give number >0!")

    while (number > 0)
    {
        digit = number%10
        score += digit
        number /=10
    }
    return score
}
fun main()
{
    println("Give number: ")
    var quantity: Int = readLine()!!.toInt()

    try {
        quantity == 0
    }
    catch (e: Exception){
        println("Can't be 0!")
    }
    catch (e: ArithmeticException){
        println(e.message)
    }
    println(sumOfDigits(quantity))
}

Upvotes: 1

Views: 611

Answers (1)

AlexT
AlexT

Reputation: 2964

There are a few concepts that you got wrong.

Let's start by talking about this:

 try {
        quantity == 0
    }
    catch (e: Exception){
        println("Can't be 0!")
    }
    catch (e: ArithmeticException){
        println(e.message)
    }
    println(sumOfDigits(quantity))

A few issues. Firstly, the assignment that is actually a check.

quantity == 0 will not alter the value of quantity it will just check if it is equal with 0. The result of this check (a Boolean) is completely ignored.

If you wish to check if quantity is 0, you need to do it in an if statement.

The second confusion that I think you have is regarding what a try/catch block does. It tries some piece of code, and if that code fails (aka the code throws an exception), the catch can be used to mitigate the risk of the procedure stopping. In some cases, it is ok for the procedure to stop, then the catch is used to write more info in the console, to override the exception's message, or to call other pieces of code before the process ends.

The third confusion is on the catch blocks. catch (e: Exception) will catch all possible exceptions (but not all possible Throwables). That means that the second catch block of e: ArithmeticException will never happen since the first one is more generic.

Considering that, and assuming that you want the process to actually stop when the input is 0, then all you need to do is:

if(condition==0) return //close the program silently

OR

if(condition==0) error("Can't be 0") //throw an exception with this message

But, your sumOfDigits already checks if the number is less than 0, why not make it check if it is less than 1? Since we don't want 0's, starting from 1 is the natural process we should follow.

Taking this into consideration, then we get this:

fun main() {
    println("Give number: ")
    var quantity: Int = readLine()!!.toInt()

    println(sumOfDigits(quantity))
}


fun sumOfDigits(quantity: Int): Int {
    var score = 0
    var digit: Int
    var number: Int = quantity

    if (number < 1) throw ArithmeticException("Give number >0!")

    while (number > 0) {
        digit = number % 10
        score += digit
        number /= 10
    }
    return score
}

This can also be improved.

  • There is no need for quantity to be variable, we never change its value.
  • The digit property in the sumOfDigits function is redundant, as we can just assign the result of number % 10 directly to the score.
  • If we truly want, we can attempt to catch the exception that would happen if the user inputs a non number character.
fun main() {
    println("Give number: ")
    val userInput: String = readLine() ?: error("Please provide an input") //this exception is thrown when the input is null (due to the Elvis operator `?:`)
    val number: Int

    try{
        number = userInput.toInt()
    }catch (e: NumberFormatException){
        println("A number needs to be provided. Input `$userInput` cannot be read as number")
        return 
        /*this will just close our procedure, we could also just throw our own exception
          instead of hte println, or just leave the normal exception propagate*/
    }

    println(sumOfDigits(number))
}


fun sumOfDigits(quantity: Int): Int {
    var score = 0
    var number: Int = quantity

    if (number < 1) throw ArithmeticException("Give number >0!")

    while (number > 0) {
        score += number % 10
        number /= 10
    }
    return score
}

Now, as a Kotlin dev, I would write this quite differently, and I would not advise a beginner to use Kotlin like this. But I believe that it is still interesting for you to know that your procedure can be minimalised quite easily. (Note, this is not readable, and would require proper documentation if you decide to code things this way)

fun main() {
    println("Give number: ")
    //will take an input from the user and throw an exception if the input is null
    val input = readLine() ?: error("No input given")

    //will throw NumberFormatException if the input is not a number. We are ignoring the actual result of the call itself
    input.toInt() 
    
    /*
        will take each char of the string and create a sum with the given selector. Since the given selector is
        the char itself minus 0, it will actually sum each char, in our case, each digit
    */
    val sum = input.sumBy { it - '0'}
    
    println(sum)
}

Upvotes: 2

Related Questions