20

I mostly understand the potential issues with checked exceptions and why Kotlin omits them. However, the issue I am encountering is I can't find any foolproof way of clearly indicating to the caller what exceptions a function may throw.

I have run into the issue countless times in Python where my program will crash after running for months because I didn't realise a function from some library I'm using can raise a particular exception. Although being forced to catch exceptions can be quite problematic, it is nice to clearly see all the potential exceptions a function can throw.

So back to the question, is there any simple way to see what exceptions a function throws in Kotlin? What about for methods written in Java that are being called from Kotlin? Even if just in tooling (intelliJ). I'm not counting writing it in javadoc or kdoc as the writer of the function you're using may have omitted it.

zjuhasz
  • 1,489
  • 12
  • 30
  • I suppose it's impossible. Consider the following: `val cls = Class.forName(a); val method = cls.getMethod(b); method.invoke()`, where `a` and `b` are read from file or provided by user input. How can you know what exceptions this code throws before you execute the code? – Alexey Andreev Mar 17 '16 at 05:29
  • 2
    I mean you're going to be missing all sorts of type information when you use reflection. Wouldn't the same issues apply if you were using reflection in Java? I think it would still be useful to know what exceptions can be thrown in the cases where the type is known at compile time. – zjuhasz Mar 17 '16 at 05:45

2 Answers2

6

If you want to know what exceptions a Java method throws when called by Kotlin from IntelliJ, you can use the F1 key shortcut to pull up the javadoc and see the throws declaration in the popup menu.

Kotlin functions can declare exceptions that it throws using the @Throws annotation. Annotations are obviously optional, so you probably can't expect this to always exist. Unfortunately, when you use the F1 keyboard shortcut on a method using @Throws, it doesn't show the exceptions declared to be thrown. Java calls into these methods are required to catch these exceptions declared in the annotation.

Kotlin javadoc can use the @throws javadoc annotation to further provide definition exceptions that can be thrown in a function. These do appear in javadoc and in F1 help popups. An of course this is also optional.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • 2
    Javadoc is a fine solution for my own code but the issue is the javadoc in many libraries leaves a lot to be desired and you're really counting on the developer to have thorough documentation on everything. I guess I was more looking for something like a warning in intelliJ or another tool where I wouldn't have to manually check anything so I don't accidentally miss an exception from a library function that isn't obvious. It seems like such a thing does not exist so far :/ – zjuhasz Mar 17 '16 at 05:57
  • 2
    Yeah, that's kind of the way unchecked exceptions work. I know your pain. – Doug Stevenson Mar 17 '16 at 06:05
  • 2
    F1 key? Better write about IntelliJ action name, not shortcut which may be remapped. Doesn't work for me. – Pointer Null Sep 27 '17 at 08:13
  • Not sure what function he referred to with `F1`, for me that always just brings up the IDE online help. To look up method/class documentation I would always recommend `Quick Documentation` (default shortcut is `Ctrl`/`Cmd` + `Q`). And this documentation *does* show the exceptions defined with the `@Throws` annotation. – Thorbear Aug 28 '18 at 07:12
1

This library called Result is a nice solution. It returns a Result object with a value or an exception and changes its type to success or failure accordingly. They can also be chained together using the libraries map and flatmap functions which helps eliminate nested try-catch blocks. Very cool, I recommend anyone who finds this question check it out.

Of course this only helps with functions that take advantage of it so I'm not marking this as an answer.

zjuhasz
  • 1,489
  • 12
  • 30