В Kotlin чрезвычайно легко создавать пользовательские исключения. Ниже приведен пример, который принимает code
в качестве аргумента:
class PortraitRequestFailedException(val code: Int) : RuntimeException()
* code
содержит код ошибки ответа http, возвращенный с сервера. Проблема в том, что когда об этом исключении обычно регистрируется регистратором, например Timber.e(exception, "Error loading portrait cover photo url")
, code
теряется в выводе:
2020-02-14 13:50:59.886 15942-16232 E/PortraitManager$watchCoverPhotoUrl: Error loading portrait cover photo url
com.example.data.PortraitManager$PortraitRequestFailedException
at com.example.data.PortraitManager$loadCoverPhotoUrl$1.call(PortraitManager.kt:139)
Конечно, я мог бы добавить предложение и дескриптор when exception is PortraitRequestFailedException
конкретно эта конкретная ошибка, но я не хочу этого (особенно если все исключения в Kotlin не проверены, и я не могу знать, какой тип ожидать).
Я нашел простой способ передать код RuntimeException
в качестве параметра message
:
class PortraitRequestFailedException(val code: Int) : RuntimeException(code.toString())
2020-02-14 13:40:32.878 430-857 E/PortraitManager$watchCoverPhotoUrl: Error loading portrait cover photo url
com.example.data.PortraitManager$PortraitRequestFailedException: 403
at com.example.data.PortraitManager$loadCoverPhotoUrl$1.call(PortraitManager.kt:139)
Но такой подход мне кажется слишком многословным (мне нужно сослаться на code
в конструкторе родительского класса), и он просто напечатает PortraitRequestFailedException: 403
, не сообщая, на что ссылается 403 (представьте, что здесь имеется более одного аргумента).
Поэтому у меня возникла идея определить свое пользовательское исключение как класс данных:
data class PortraitRequestFailedException(val code: Int) : RuntimeException()
Поскольку классы данных в Kotlin генерируются автоматически Метод toString()
в форме PortraitRequestFailedException(code=403)
, такая запись имеет все преимущества, которые я хочу, без добавления подробности или шаблонного кода. Журнал выглядит следующим образом:
E/PortraitManager$watchCoverPhotoUrl: Error loading portrait cover photo url
PortraitRequestFailedException(code=403)
at com.example.data.PortraitManager$loadCoverPhotoUrl$1.call(PortraitManager.kt:139)
Видите ли вы недостатки такого подхода? Есть ли опасность обработки исключений как классов данных?