7.8. Exceptions
Exceptions offer a mechanism to capture run-time errors in our code. Using exceptions in a proper way produces more robust code. Its syntax is very similar to Java:
try {
// Code to watch
}
catch (e: ExceptionTypeToCatch)
{
// if there is an exception then execute this code
}
In the following example we try to convert a string that does not contain a number to Int.
var number : Int
try {
val str = "hello"
num = str.toInt()
}
catch (e: NumberFormatException)
{
Log.d("error", e.stackTraceToString())
}
In the previous snippet, we have used stackTraceToString
to display the error message and call stack in the Logcat window. In this example, we would see the following information in Logcat:
2022-04-08 15:36:15.200 26410-26410/com.uoc.kotlin_advanced D/error: java.lang.NumberFormatException: For input string: “help”
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at com.uoc.kotlin_advanced.MainActivity.onCreate(MainActivity.kt:106)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Since all exceptions inherit from a class Exception
, we can capture all errors by writing a catch statement for class Exception
.
try {
val str = "hello"
num = str.toInt()
}
catch (e: Exception)
{
Log.d("error",e.stackTraceToString())
}
Multiple catches can be defined to execute different code depending on the type of Exception.
try {
val str = "hello"
num = str.toInt()
}
catch (e: NumberFormatException){
Log.d("error",e.stackTraceToString())
}
catch (e: Exception)
{
Log.d("error",e.stackTraceToString())
}
We can also create our own exceptions by inheriting from the Exception
class:
class LowNumberException(message: String) : Exception(message) {
}
To launch an exception, we use the throw
statement. In the following example we launch an exception of type LowNumberException
if the number is less than 10.
var num: Int
try {
val str = "2"
num = str.toInt()
if(num<10){
throw LowNumberException("Low Number")
}
}
catch (e: LowNumberException){
Log.d("LowNumberException",e.stackTraceToString())
}
catch (e: NumberFormatException){
Log.d("error",e.stackTraceToString())
}
catch (e: Exception)
{
Log.d("error",e.stackTraceToString())
}
Finally, we can launch the base exception by doing:
throw Exception("Error!")