15

And how do we handle this when we are calling a method in Java which throws exceptions ?

my code is in kotlin and I am using a 3rd party library which is written in java. I call a method of this library which throws few custom exceptions in some cases. Now kotlin doesn't enforce me to handle this exceptions and in which case application would crash. What's the best way to handle this ?

  • 1
    Even in kotlin you can use try-catch block. – Kaushik Burkule Oct 31 '19 at 08:13
  • 2
    @KaushikBurkule, I know that there is try-catch in kotlin. The question is how do you get to know that you have to wrap a piece of code with-in try-catch as kotlin compiler doens't enforce to do. –  Oct 31 '19 at 09:16
  • 3
    In a well defined API this should be documented in the Kotlin-doc of the function. The enforced catch mechanisms where removed since the anti-pattern of declaring an interface to throw an "Exception" can be seen all over many java code libraries even if the actual implementation does never throw any exception. – Markus Spöri Oct 31 '19 at 09:22

1 Answers1

17

When Java introduced checked exceptions — where the compiler enforces that most exceptions are either caught or declared to be thrown — it was a fairly new idea.  Java was a much safer language than most of its predecessors: all behaviour defined and consistent across all platforms, and many features intended to prevent crashes, unexpected behaviour, or fragile coding.  So checked exceptions fitted in well with the language's philosophy.

But in the years since, many people have come to the conclusion that checked exceptions were a mistake.  I'm not totally convinced, but here are some of the reasons:

  • They're verbose.  It's common for methods to include many trycatch blocks, and/or to declare many exceptions.  Also, if there are 6 levels of method call between where an exception is thrown and where it's caught, the exception will need to be declared by 5 methods.

    Kotlin does away with much of Java's boilerplate, and doing away with checked exceptions fits in with that.

  • They encourage bad practices:

    • Trying to handle exceptions in the wrong place, i.e. at the wrong level of abstraction, where nothing useful can be done.
    • Pointless catch blocks (especially dangerous ones which do nothing but logging the error).
    • Catching/declaring Exception instead of the specific subtypes.
    • Cheating by wrapping checked exceptions in unchecked ones such as RuntimeException.
  • They increase coupling between modules.  If you're using a library method which adds a new exception, then all code calling that method needs to be updated to handle or rethrow it.

  • They require exceptions to be translated between different levels of abstraction.  (For example, a DB-access layer might have to convert a socket-timeout exception into a database-unavailable exception.)  This is tedious, but necessary to avoid exposing implementation details. 

  • They don't work well with inheritance.  If the method you're implementing/overriding isn't declared to throw a particular checked exception, then your implementation can't throw it either.

  • They don't work well with lambdas.  In Java, lambdas are implemented using Single-Abstract-Method interfaces, and so those methods must either declare the possible exception (in which case every usage must handle or declare it), or the lambda body must catch the exception.  Both options greatly increase the conceptual weight as well as the code needed to use lambdas, destroying the conciseness which is one of their main benefits.

    Kotlin's implementation is fairly similar (though it uses its own KFunction interfaces), and would suffer the same problems.

With all these problems, it's clear that checked exceptions are a mixed blessing at best.  And I can see why Kotlin has done away with them.

I do worry that it may result in programs that are less robust (and less well documented).  But in the two years I've been using Kotlin, I haven't seen any obvious cases of this.  So I'm holding off judgement for now :-)

(See also this question.)


As to how to handle your particular case, I suggest you do the same as you'd do if Kotlin had checked exceptions: see what exceptions the method you're calling can throw, work out how/where best to handle them, and handle them!  Just because Kotlin isn't forcing you to do so, doesn't mean it's not still a good idea!

Community
  • 1
  • 1
gidds
  • 16,558
  • 2
  • 19
  • 26
  • 9
    Ok, so in kotlin we are forced to check the api method to see if it throws any exception and handle accordingly. Isn't it a bit tedious ? In Java we would get compile time error if we don't handle. And what if we miss out, and it's going to crash in production. –  Nov 07 '19 at 07:26
  • 8
    Yes, that's about the size of it. And I share your concern... – gidds Nov 07 '19 at 08:13