-
Notifications
You must be signed in to change notification settings - Fork 362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error handling in the Kotlin language #81
Conversation
You should address the problem of backwards compatibility with this proposal. This is a major breaking change to the language and thus it is a no-go in Kotlin's world (we have no plans to turn Kotlin into Swift in this respect). I don't think there can be a discussion on the merits of this proposal until it addresses the issue of introducing those changes without breaking existing code. |
@elizarov I understand and took quite some time to consider such a breaking change. Here are my reasons:
Of course, migration tool designers might have better ideas, but this is a start. |
I think (1) is a key point where we disagree. Having successfully used Kotlin in many projects at JetBrains and listened to feedback from the users of Kotlin pre-1.0 and in the 1.0.x and 1.1.x timeframe, we do not see that error handling in Kotlin isn't working as designed. Choosing an error handling strategy is a major design choice in a language, and we made our choice consciously, knowing which alternative approaches exist. We do not see any evidence that the approach we chose is broken. |
Moreover the more you use Kotlin the less you use exceptions as a way to deal with error states, but more as a way to actually crash your program if something gone terribly wrong with enough info to trace it back. Maybe it's just my experience though. Kotlin sealed classes feels like a much more appropriate way to introduce success, empty, error, etc states for the data types in the code. |
I'm pasting my previous comment on the proposal here for visibility: IMO, making code that throws an exception fail compile time checking might be a little Call sites: expressions that call methods with: I like your use cases (call sites) B, C, D and E. Thinking about this, it might make sense to add a parameter (e.g |
Hey all! Sorry it took me a couple days to respond. Here's a batch:
The reason I say that Kotlin's error handling is "broken" is because you can have this: class Crash: Exception("Crash!")
fun danger(i: Int): Int {
val ret = i % 2
return when (ret) {
0 -> throw Crash()
else -> ret
}
}
fun main(args: Array<String>) {
println(danger(1))
println(danger(2))
} Here, we only know by examining the In my opinion, this is not something that should be a problem in modern languages. I tried to make it clear in my proposal, but the main driving reason I did this is because I import JARs made with Java/Scala/etc. and use the libraries of Java SE, Android, etc. which are very eager to throw exceptions, especially on I/O and networking calls. Maybe one day, we could use Kotlin for these, but as it stands now, Kotlin stdlib is so barebones you need the help of external SDKs which love throwing, so Kotlin needs to be good at catching (notice most of my proposed syntax involves catching, and not so much for throwing). Right now, Kotlin is about as good as Java in this regard. Call Sites B, C, D, and E were the real meat of this anyway. I threw A in there because it seemed reasonable given how often people ignore the actual value of the thrown exception, and how unintuitive it is to catch Throwable. I'm not tied to Call Site A. I love your idea to have syntax that makes the exceptions lenient. This reminds me of Swift's |
@BenLeggiero Do you actually think that we were unaware of the possibility to write such a code snippet when we were designing Kotlin's error handling? To expand on this, the only reason to make a major, backwards incompatible change to the design of a core part of the language is new information. Like, for example, a new breakthrough in solving a problem explored in another language or a research paper. Or the discovery that some of our assumptions do not hold in a specific important use case that we weren't aware of. Or unanimous feedback from a large part of the community that a shortcoming in the design of the language prevents them from adopting it. In this case, I see no new information. We've always known that Java libraries like to throw exceptions. We've also known how inconsistent the design is (you need to check exceptions from closing a socket, but don't need to check exceptions when you parse a number to a string). We know how much code in enterprise apps is dedicated to mindless catching, logging and rethrowing of exceptions. And we don't see any specific use case or community where Kotlin's design for exception handing is a major obstacle to its adoption. Of course, Kotlin is not perfect, and of course feedback is welcome. To me, it looks like the best way to address a problem is through better tools - tools that run separately from the compiler and can have much more fine-grained configuration concerning the types of exceptions for which you want special handing and the APIs for which you want that handling. I believe that a solution can be implemented without any changes to the language, simply by building additional inspections in the IDE. |
I don't think it's practical to require all exceptions to be handled/declared at all times in our setting. For one thing, it's not clear how we can work with Java code that does not declare RuntimeExceptions. So, I think the only way we get anything like this in the language is through a compatible extension, not a breaking change. On a side note, we are now looking into a more general mechanism for effect capturing, and optional checking of exceptions may be a nice use case for that. |
Enough discussion here. To sum up:
|
@elizarov thank you for following up.
|
Full text is here
Synopsis
This proposal attempts to give Kotlin's error handling the same delight, peace-of-mind, and unambiguous terseness that the language already generally has.
Quick example: