In this tutorial, we’ll be discussing Exception Handling in Kotlin.
What are Exceptions?
Exceptions are something that can break your program. That makes Exception Handling an essential part of any Programming Language. Using Exception handling you can handle errors and prevent runtime crashes that can stop your program. Instead, using Exception Handling you can handle failed conditions gracefully and continue with your program flow.
Checked vs Unchecked Exceptions in Java
Checked Exceptions are typically set on methods and are checked at compile time.
On the contrary, Unchecked exceptions derive from RuntimeExceptions and are checked at runtime.
Kotlin Exceptions
All Exceptions descend from the Throwable class.
To throw an exception we use the throw
keyword.
1 2 3 |
throw Exception("Oops. Something went wrong") |
In Kotlin there are no checked exceptions. That means there is no throws keyword.
try-catch-finally
To handle exceptions we use the try-catch
block. The piece of code that has a possibility to give an exception is set inside the try block. The exception is caught inside the catch block. Irrespective of what happens, the finally block is always run.
The finally blocks is optional. It’s generally used to release any resources that were used in the try-catch.
Typically a try can have multiple catches. Only the first matching catch would be run. Hence it’s recommended to stack the catches in the order: Specific Exception to General Exception.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
fun main(args: Array<String>) { try { var a = 0 var x = 7 / a val v = "Journaldev.com" v.toInt() } catch (e: ArithmeticException) { println("Arthimetic Exception") } catch (e: Exception) { println("Exception occured. To print stacktrace use e") } finally { println("Finally. It's over") } } //Prints //Arthimetic Exceptions |
Once an exception in the try
block is found, it’ll not execute anything else in that try block.
We can even use a try
with a finally
.
1 2 3 4 5 6 7 8 |
try{ throw Exception("Hi. how are you?") }finally { println("Finally. Good.") } <img class="alignnone wp-image-33607 size-full" src="https://all-learning.com/wp-content/uploads/2018/04/kotlin-try-catch-finally1.png" alt="kotlin-try-catch-finally" width="1200" height="628" /> |
With a try, at least one catch or finally block must be present.
throw
is an expression which would print the stack trace as well.
Try is an expression
The value executed in a try-catch block can be returned and stored in a variable.
1 2 3 4 5 6 7 8 9 10 11 |
fun main(args: Array<String>) { var x= "Androidly.net" var a = try { x.toInt() } catch (e: NumberFormatException) { "This is a string" } println(a) x = "5" a = try { x.toInt() } catch (e: NumberFormatException) { "This is a string" } println(a) } <img class="alignnone wp-image-33608 size-full" src="https://all-learning.com/wp-content/uploads/2018/04/kotlin-try-catch-finally3.png" alt="kotlin-try-catch-finally" width="1200" height="628" /> |
In the above code, we’re able to set the variable a with two different type of values.
If the try statement doesn’t execute the value of catch is set.
Irrespective of which is set, the finally
statement is never set as the expression.
fail function
This is a shorthand for catching exceptions as shown below.
1 2 3 4 5 6 7 8 9 10 11 12 |
import kotlin.test.fail class User { var name: String? = "" } fun main(args: Array<String>) { var user = User() user.name = null val n: String = user.name ?: fail("No name found") print(5) } |
If the fail statement is executed the program won’t run after it’s printed.
Implicitly the fail statement contains a throw keyword.
The fail function looks like this:
1 2 3 4 5 |
fun fail(message: String): Nothing { throw IllegalArgumentException(message) } |
Nothing is a special return type which throw returns.
In the above example, the fail function prints the stack trace too which we don’t always want.
We can override the fail function to just print the message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class User { var name: String? = "" } fun main(args: Array<String>) { var user = User() user.name = null val n: String = user.name ?: fail("No name found") println(n) print(10) } fun fail(message: String): Nothing { val throwable = Throwable(message) Thread.setDefaultUncaughtExceptionHandler { t, e -> System.err.println(e.message) } throw throwable } //Prints No name found |
Using Inline Functions with exception handling
We’ve discussed Inline Functions in Kotlin here.
Why use Inline Functions?
They cause no overhead.
Now, we’ve seen that try-catch blocks can get messy and verbose.
Let’s use an inline function to make it concise since that’s where the strength of Kotlin code lies in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
fun main(args: Array<String>) { simpleTryCatch { var x = 0 var y = 7 var z = y / x } simpleTryCatch { var x = "Androidly" var number = x.toInt() } } inline fun simpleTryCatch(action: () -> Unit) { try { action() } catch (t: Throwable) { println("Caught something. ${t.message}") } } <img class="alignnone wp-image-33609 size-full" src="https://all-learning.com/wp-content/uploads/2018/04/kotlin-try-catch-inline-function.png" alt="kotlin-try-catch-inline-functions" width="1200" height="628" /> |
This brings an end to this Kotlin tutorial on Exception handling.