Hacker News new | ask | show | jobs
by vetinari 1504 days ago
> But to me the superb thing about exceptions, is that error handling can be done where it makes sense.

Not necessarily. With exceptions, it is easy to be a cause of error and just throw the exception, then expect up the stack to handle it. Which of course has no idea how, it didn't control the cause in the first place.

Forcing error handling as near as where error can happen prevents this.

2 comments

Actually, up the stack is usually the only place that knows how to handle the error. For instance sometimes dumping to stderr is the right thing to do, other times logging it, other times displaying a generic crash GUI, sometimes display a customized UI. There may also be times when the exception can be handled in a better way, with fallbacks for example.

The Rust/Go approach always makes me laugh. Normally in engineering or anything where reliability matters, panicking is understood to be a bad thing to do and people go through extensive training to ensure they don't do it. Somehow these language communities decided that panicking and giving up on the spot is a smart behaviour.

> Somehow these language communities decided that panicking and giving up on the spot is a smart behaviour.

Oh, come on, that's a straw man.

Just because panic! exists as a "abort-program-with-a-message", does not mean it's somehow encouraged above using idiomatic error handling.

Just as you can do the same thing in languages with exceptions. Sometimes exiting the program is the right thing to do.

Panic is idiomatic error handling. Take something as basic as indexing into a list. Get it wrong and Rust will panic.

Sometimes exiting the program is the right thing to do.

Yes, but it's very rare that the code where something went wrong is in the position to decide that. The survival of the entire process is not a decision to delegate to every possible line of code or library author.

Consider a very common case where I benefit from exceptions every day - my IDE. IntelliJ hosts a bazillion plugins, of varying quality. These plugins like to do very complex analysis on sometimes broken and incoherent snippets of code, that may be in the process of being edited. In other words it's a nightmare to correctly predict everything that can go wrong.

Not surprisingly, sometimes these plugins crash. And you know what? It doesn't matter. A lot of the code is just providing optional quality-of-life features like static analysis. If one of them goes wrong, IntelliJ looks at the exception and figures out which plugin is likely to blame, it examines the type of error and maybe gathers editor context, it can report it easily to a central server that then groups and aggregates exceptions based on stack traces. Meanwhile as a user, it doesn't bother me because it's fine to just not have that analysis show up in the editor.

If every time an IDE plugin encountered an unexpected situation it aborted the entire process it'd be insane. The plugin ecosystem could never scale that way. People would be afraid of installing/upgrading plugins and that in turn would discourage people from writing them or adding features to them.

> If every time an IDE plugin encountered an unexpected situation it aborted the entire process it'd be insane.

What if a plugin developer used `System.exit(-1)` in their catch block. How's Intellij going to handle that?

A very popular eclipse plugin did this in past and would bring down the entire IDE when a particular exception happened.

In reality nothing does that because, well, why would you when you have good exceptions? But even so, Java has a way to block that using the SecurityManager. Now they are deprecating the SecurityManager "how do I stop code calling System.exit" is one of the use cases they're planning replacements for.
I'm sure there would still be ways to bring the entire process to halt(for example, spawn thousands of threads with infinite loop). My point is just because a bad developer wrote bad code doesn't mean that a tradeoff chosen for a language design is necessarily bad.
> The survival of the entire process is not a decision to delegate to every possible line of code or library author.

Stated like that, who can really disagree?

I remember when I was writing a bunch of Go when the language was still very new (2009 - 2011). One of the most popular use cases for the language was making websites. All sorts of unexpected problems caused the entire website to go down, due to unexpected panics here and there. The suggested solution from the Go team was to just restart the web-server whenever it was killed by a panic. Surely that cannot be the best way to do it..

>Panic is idiomatic error handling. Take something as basic as indexing into a list. Get it wrong and Rust will panic.

This is not really true. If you are indexing into something that may fail you use the `get` method which returns an `Option` if the index is out of bounds. The index operator is just a shorthand for `v.get(i).unwrap()` pretty much.

https://doc.rust-lang.org/std/primitive.slice.html#method.ge...

Yes, but the problem is that very often a programmer "knows" an index operation can't fail because they haven't thought of a case where it is a different size, or code gets refactored and assumptions are invalidated, etc.

The panic mentality comes from people who have spent most of their life writing C++, in which if anything goes wrong like an out of bounds index, memory might be corrupted in arbitrary ways, and in which you don't have a GC to clean up after you. Writing exception safe code is much easier in type safe GCd languages, and many programming errors end up being recoverable.

> it is easy to be a cause of error and just throw the exception, then expect up the stack to handle it.

Agree, this can happen. Perhaps the bad attempt at fixing this in Java for instance - checked exceptions, made people dislike exceptions ever more. The caller "has to handle" the exceptions or re-throw them of course. Even though RuntimeException's can come from anywhere at anytime, so "guard" provided by checked exceptions just made a complete mess of things. People are lulled into thinking that methods without the 'throws BlaBlaException' signature are safe and so on.

I guess no language is 100% on everything, but I've always felt that exceptions are one thing I really like; especially when a language manages to do them correctly.