Beware of wrapping `runCatching` around your suspending function calls like network calls: it also catches coroutine cancellation exceptions that you might not want to swallow, or you might break cooperative cancellation! In general you should try to only catch exceptions that you expect and want to handle. When working with coroutines, you can expect cancellation exceptions, but do you want to handle them (catching and swallowing also is handling)? Often that is not the case! Similarly, on the JVM you can expect all kinds of throwables like out of memory errors. You might catch those too, which likely is not a good idea.
Still, `runCatching` is great to use, but make sure that you rethrow exceptions that you don't want to handle: check for the expected exception type(s) and only handle those.
Also, idiomatic Kotlin tries to avoid throwing exceptions, see this excellent article: https://elizarov.medium.com/kotlin-and-exceptions-8062f589d07
Instead, try to embed error states in your type system by returning `null` instead of throwing, or by materialising result types, like through using the `Result<T>` API.
Third party dependencies (libs, system) might not be as modern and throw exceptions. That's where try-catch comes in handy: catch only what you want to handle.