Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'd like to hear thoughts on CheckedExceptions in part 2. IMO, they are a disaster - most projects degrade into all methods having a "throws Exception" clause. But I'm not sure if there is any consensus on how the CheckedException haters like myself work around them. I use Runtime exceptions everywhere, but it's a pain/boilerplate to convert them.


Not all checked exceptions are bad. The main problem is that the core Java libraries tend to use them too aggressively and now of course cannot be changed. You really have to be sure that the caller MUST handle a particular occurrence and anything else is a bug to make an exception checked. But, I do find it helps me feel more confident in my code. Everyone hates writing error handling code, but at least with checked exceptions you can see whether it's been done properly or not.

But in Java 8 for the times when I want to disable it, I just use the following code:

    public interface UncheckedRun<T> {
        public T run() throws Throwable;
    }

    public interface UncheckedRunnable {
        public void run() throws Throwable;
    }

    public static <T> T unchecked(UncheckedRun<T> run) {
        try {
            return run.run();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        }
    }

    public static void uncheck(UncheckedRunnable run) {
        try {
            run.run();
        } catch (Throwable throwable) {
            throw new RuntimeException(throwable);
        }
    }

    public static void ignoreAndLog(UncheckedRunnable runnable) {
        try {
            runnable.run();
        } catch (Throwable t) {
            log.error("Ignoring error", t);
        }
    }
Then you can write

Foo result = unchecked(() -> getAndMaybeThrow(a, b));


I think some of the additions in Java7/8 will make them a little easier to work with. The worst thing used to be the necessity to nest multiple try/catch blocks, or repeat identical code between separate catch blocks because different components throw different errors. This is now dramatically helped by the multi-catch and other additions.

Like you, I use a lot of RuntimeExceptions, but I think in it's important not to overlook the benefit of checked exceptions: if you're trying to write reliable software looking up and understanding every possible failure mode of every API you are calling is an almost unbearably tedious and impossibly boring task. In principle, having the compiler check and tell you "Hey, there's this error that could occur and you haven't defined how your code is dealing with that" is a tremendously useful thing. Our human tendency to focus only on the successful path through our code and then ignore all the possible failures is terrible bias if you're trying to make code that behaves the right way under ANY circumstance. So I support checked exceptions, and I hope the new improvements in Java make them more workable and accepted. There probably need to be more improvements, something long the lines of STM type features before we'll get there though, I think.


1) try introducing a Checked Exception in a commonly used method. Soon you'll be updating 100s or 1000s or methods.

2) checked exceptions don't play well with interfaces (APIs) for similar reasons. any interface user must change their code simply because some new checked exception bubbles up now

3) checked exceptions lead to terrible error handling and hiding bugs/system problems. instead of letting exceptions bubble up - java coders almost always write code that either swallows or simply logs the exception and continues along as if nothing happened. If my bank deposit fails, I don't want the failure to just end up in a log file - I want to know it! Exceptions were designed to usually bubble up and be exposed/handled in a standard way at the top level thread. They are usually not recoverable.

4) they lead to bugs. I very rarely see anyone handle the statement/resultset handling of JDBC code correctly.

5) if they are such a good idea, why does no other language ever created has them?


> 1) try introducing a Checked Exception in a commonly used method. Soon you'll be updating 100s or 1000s or methods.

Try doing that in a code base without checked exceptions. You just created 100s or 1000s of unrecognised errors in other code without realising it. The problem is not the checked exception. The problem is you changed something 100s or 1000s of things are relying on to add a new failure mode.

> Checked exceptions lead to terrible error handling and hiding bugs/system problems. instead of letting exceptions bubble up - java coders almost always write code that either swallows or simply logs ....

Well, I agree up to a point. But that is much to do with how tedious and verbose the error handling itself is which is more about the language than the concept of checked exceptions.

> they lead to bugs. I very rarely see anyone handle the statement/resultset handling of JDBC code correctly.

see above

> 5) if they are such a good idea, why does no other language ever created has them?

Well, you can also say, if they are such a bad idea, how come one of the world's most popular and used language builds them into all its core APIs? They can't be that terrible or Java would never have got so popular ....


I think you are falling into the trap of thinking you can usually recover from an exception. Exceptions are usually caused by one of two things:

1) system error (no more DB connections, hard drive full, etc)

2) a bug

neither of these are recoverable, you just need to stop the task at hand and notify someone that the situation needs to be fixed. Trying to handle it and recover is usually a fools errand that results in hiding the problem

There are cases that you do want to handle exceptions. In these cases, yes catch the exception and handle it. But these cases are the 10% case, hence the default behavior of making the caller handle the exception isn't desirable.

This link from 2003 articulates the point better than I can: http://www.artima.com/intv/handcuffs.html


If Java forced you to handle the exception that would be convincing, but it doesn't. It merely says, if you don't want to handle it, add to your signature that you throw an exception so that at least someone upstream has a chance to know that the error might occur. I'm not arguing at all btw that the way Java does it is good. Merely that there's a case for checked exceptions, especially if you are actually trying to write "reliable" software.


Depending on the software and what it's used for, the first class or errors might and should be recoverable from.


Well, there's not much to discuss about checked exceptions. The general consensus in the Java community that it was a very good idea in theory, that hasn't worked out well in practice. New API designs usually don't introduce new checked exceptions. Those that are there - are there, and new ones aren't being added, so there is really not much to argue over.


I quite like checked exceptions. They're actually one of the few things that keeps me writing java for more projects instead of switching more of my time to golang -- golang takes the far opposite approach, and with either returning error codes, or using golang's borderline untyped panic (yes, yes, you can panic typed errors... but it's an incredible PITA to try to construct an error type hierarchy and impossible do terse typed catch blocks with it) doesn't scale well for projects more than about 4ksloc in my experience.

Exceptions signatures, like anything else, need aggressive refactoring to remain a useful part of an API. Always remove throw declarations that aren't needed. Always refactor the exception type hierarchy as your project evolves to keep it sensible.

The worst of typed exceptions I've felt recently is the JGit API (don't get me wrong, JGit is an amazing piece of work; but its sharpest parts are the error handling). There's inchoate masses of IOExceptions from some pieces, JGitAPIExceptions in others, and none of them compose nicely so that when I do large amounts of work I can summarize the error handling up to a few types of conceptually similar problem. And several JGit commands throw checked exceptions for what are essentially fuck-ups in builder patterns, which have been compile-time issues every time I run into them, thus a source of huge irritation (these are prime examples of where you should use unchecked exceptions).

On the other hand, the project I was using that same JGit API in has been one of the best examples of why typed exceptions can be a good idea. This project grew out of a python->java rewrite, and so in the original translation used completely unchecked exceptions as a holdover from the python form. (Why rewrite? It needed to go cross-platform and I needed a stable git api; libgit2 still couldn't clone at the time, so it was jgit or gtfo.) And as I kept working on the project and writing test cases... time and time again, converting things to typed exceptions and refactoring the exception hierarchy paid huge dividends in code quality, huge improvements in API consistency, and raised the quality of tests and final product alike because similar error cases ended up with similar exception types, and tended towards similar handling as I refactored similar exceptions types into one... #wining.

tl;dr being irritated by methods that claim to throw too many exception types is good and healthy. The fix isn't to toss checked exceptions out the window: the fix is to take the pain, and use it to fuel a good API with a tightly controlled and easily understandable set of failure modes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: