Исключения в Kotlin — краткое руководство

Привет. Сегодня мы рассмотрим исключения в Kotlin на реальных примерах. Это будет краткое, но емкое руководство по обработке ошибок в Kotlin.

Итак, исключения в языках программирования — это события в процессе выполнения программы, возникающие в ходе нарушения корректной работы. Например, при запросе данных на сервер может «упасть» соединение, данные полученные по Сети могут быть некорректными или же запрашиваемый файл для записи или чтения не существует и т.д. Ежели не обработать исключение, то наша программа «падает» в аварийном режиме, что не очень хорошо.

Kotlin try..catch..finally

Начнем с того, что все исключения в Kotlin — являются непроверяемыми, и наследуют стандартный класс Throwable. Исключение с помощью Throw мы рассмотрим далее. Пока начнем с блока try..catch..finally — самого часто используемого способа обработки исключений в Kotlin.

try {                 
    // основной блок с кодом           
} catch (ex: Exception) {
    // обработка 
} finally { 
   // необязательный блок          
}

Теперь рассмотрим детальнее. Блок try служит для размещения кода, который может вызвать исключения — сетевой запрос, чтение файла и т.д. В catch происходит перехват события, вызвавшего некорректную работу и его последующая обработка. finally — необязательно должен присутствовать, служит для исполнения неких завершающих действий. Следует отметить, что можно размещать более одного блока catch для обработки exception в Kotlin.

Теперь реальный пример — функция для HTTP GET запроса данных из Сети.

fun getData(url: String): String {         
    val sb = StringBuilder()         
    with(URL(url).openConnection() as HttpURLConnection) {             
        try {                 
            val text = inputStream.bufferedReader().readText()                 
            sb.append(text)             
        } catch (ex: Exception) {                 
            ex.printStackTrace()             
        } finally {                 
            disconnect()             
        }         
    }         
    return sb.toString()     
}

С помощью конструкции with мы открываем соединение и пытаемся получить данные из Сети в try, записав полученную страницу в переменную text. Если у нас произойдет ошибка, то в catch мы обработаем исключение с помощью метода printStackTrace() который выбросит нам код и текст ошибки в консоль. В finally при удачном или неудачном завершении закрывается соединение.

Обработка исключений в Kotlin. Пример кода из IntelliJ IDEA
Исключения в Kotlin — IntelliJ IDEA

Исключения в Kotlin — альтернатива try..catch

Блок try..catch в Kotlin не добавляет читаемости. К тому же, когда часть бизнес логики распределена по блокам исключения, то понять как работает приложение сложнее. Но в Kotlin можно писать обработку исключений в функциональном стиле. Для этого отлично подходит конструкция when.

fun netHelper(url: String): String {
    var text = ""
    with(URL(url).openConnection() as HttpURLConnection) {
        when(responseCode) {
            200 -> text = inputStream.bufferedReader().readText()
            404 -> text = "Error handling data"
        }
        return text
    }
}

Как и в предыдущем примере, мы написали простую функцию для получения данных из Сети. Но вместо try catch в Kotlin мы использовали управляющий оператор when. Он проверяет свойство responseCode у нашего соединения, и если ответ 200, то мы получаем текст. А если код ошибки 404 (страница не найдена) то вернется «Error handling data«. Пример конечно примитивный, но показывает как можно обрабатывать исключения в Kotlin без использования try..catch

Подробнее про исключения в Kotlin можно прочитать в документации.

Throw Kotlin

Но, что если мы хотим создать свое исключение, без использования вышеуказанных способов? Для этого нам понадобится оператор throw. Рассмотрим практический пример.

fun isPrime(n: Int): Boolean {
    if (n<=1) throw Exception("Введите число больше 1")
    (2 until n).map {
        if (n % it == 0) {
            return false
        }
    }
    return true
}

Функция isPrime() проверяет, является ли число простым. При указании n равному или меньше единицы выбрасывается исключение — «Введите число больше 1». Если мы введем 1 или меньше, в консоли выведется исключение вида:

Exception in thread "main" java.lang.Exception: Введите число больше 1
     at AppKt.isPrime(app.kt:64)
     at AppKt.main(app.kt:48)
     at AppKt.main(app.kt)

Давайте посмотрим на сам класс Exception из java.lang.Exception наследуемый от Throwable. Exception имеет четыре (а всего пять) конструкторов, которые применяются в зависимости от передаваемых параметров:

public class Exception extends Throwable {
    public Exception(String message) { super(message); }
    public Exception(String message, Throwable cause) { super(message, cause); }
    public Exception(Throwable cause) { super(cause); }
    protected Exception(String message, Throwable cause,
                    boolean enableSuppression,
                    boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
}

Подробнее о классе и его методах можно почитать в официальной документации по ссылке

Выводы

В данной небольшой статье мы рассмотрели исключения в Kotlin, а именно основные приемы и методы работы. Тему эту можно конечно раскрыть намного глубже, что будет сделано позднее.

Если у Вас возникли какие либо вопросы, пожелания или замечания — пишите в комментарии, отвечу всем! До новых встреч, и удачи в освоении Котлин.

Оставить ответ