Live data from Hacker News

You’re better off using Exceptions

eiriktsarpalis.wordpress.com

171–180 of 242 posts

Re: You’re better off using Exceptions

#171
post #62

My problem with exceptions isn't so much exceptions themselves but the way they're used. The way I see it, exceptions should only be used for things that are irreconcilable, which most of the time is interpreter errors(e.g. undefined is not a function). In other words, I don't think it's that common that custom exceptions are needed outside of assertions to prevent the developer from doing something stupid. If you ar…

> A record not being found is a normal thing! It's not a normal thing for code that needs that record that wasn't found. > They literally tell you nothing and there's no way to solve them without catching/rescuing them. A null value, a plain "error" object, or an error argument in a callback would have been sufficient. If I need an exception to be raised for this kind of thing, I'll do it myself. They tell you lots:…

> It's not a normal thing for code that needs that record that wasn't found.

Why call it then?

Re: You’re better off using Exceptions

#172

My problem with exceptions isn't so much exceptions themselves but the way they're used. The way I see it, exceptions should only be used for things that are irreconcilable, which most of the time is interpreter errors(e.g. undefined is not a function). In other words, I don't think it's that common that custom exceptions are needed outside of assertions to prevent the developer from doing something stupid. If you ar…

Absolutely. Whether a method throws or not signals the intent of the code. In .NET, there are plenty of throwing and non-throwing versions of various methods. For example, there are both Parse() and TryParse() and also First() and FirstOrDefault() in Linq. Which method you use signals to the reader the expected result. If you're using Parse() then you're expecting the parse to succeed; Perhaps the data comes from a d…

In Java, you can obtain a throwing version of anything returning an Optional type:

Optional getWomp() {...}

Womp womp = getWomp().orElseThrow();

Re: You’re better off using Exceptions

#173

Earlier quoted context omitted.

The biggest issue I've seen with exceptions is that people bring up the issue when they are abused. I SORT of agree with you that an 'Record not found' exception is an abuse. This should probably be a null-object like an Optional ALA Java or Scala. They are trying to avoid returning null in this scenario. Unfortunately, if the API is designed poorly you're stuck with it. I can sort of understand why people hate check…

Nulls are also called the billion-dollar mistake (and that was decades ago; it's much more than that now). Both nulls and exceptions are ways of trying to make the main line of processing clear, while handling other lines in structured ways. There's no one-size-fits-all solution. In a lot of ways, the best response to "record not found" is that you get the same result as finding one, except with zero answers. That me…

Null _pointers_ are called the billion-dollar mistake, not null values.

Re: You’re better off using Exceptions

#174

Earlier quoted context omitted.

I also use exceptions for control-flow and I feel no shame about it. It's often the best (most concise, most performant, most understandable) solution to a problem, in my eyes.

Most concise: absolutely. Most performant: never. Most understandable: yes, but only if you are cognizant of which call paths can result in an exception and which can’t (i.e. until your code base becomes too large or you’re not the one that wrote it).

Throwing exceptions may be the most concise, but handling them rarely is.

But most importantly, static type systems lose the ability to infer what's coming so these may turn out to be really pesky problems.

Re: You’re better off using Exceptions

#175

My problem with exceptions isn't so much exceptions themselves but the way they're used. The way I see it, exceptions should only be used for things that are irreconcilable, which most of the time is interpreter errors(e.g. undefined is not a function). In other words, I don't think it's that common that custom exceptions are needed outside of assertions to prevent the developer from doing something stupid. If you ar…

I think that's too simple of a case to really make an argument either way. Just return a Some/None or Optional. Null is ok too, but not the best (it's baked in to most languages already though). But at a higher level, if the program expected something, it may be an exception. Let's consider another case. What if you made the request and your session got terminated? That will be an exception too, and I don't think anyone will add that to the result type.

I feel like encapsulation means that functions often should throw errors, because the small, one responsibility functions shouldn't have knowledge of control flow. For example, division. Anytime you divide, you might try to divide by 0. That's an exception. The / operator returns a number or throws an exception. Who would use a TryDivide function? What would it solve? The same error might be an exception in one scope, and expected in another.

I get that exceptions can be expensive, but they should be rare. Saving time on the pre-check for an exception might save more time than the rare exception. I would never throw an exception strictly for control flow, but avoid exceptions is a bad idea IMO.

But the line is very blurry.

Re: You’re better off using Exceptions

#176
post #62

Earlier quoted context omitted.

> A record not being found is a normal thing! It's not a normal thing for code that needs that record that wasn't found. > They literally tell you nothing and there's no way to solve them without catching/rescuing them. A null value, a plain "error" object, or an error argument in a callback would have been sufficient. If I need an exception to be raised for this kind of thing, I'll do it myself. They tell you lots:…

> It's not a normal thing for code that needs that record that wasn't found. No offense, but I don't know where that idea comes from. Systems are checking for records all the time in ways where the absence of data doesn't necessitate throwing an exception. For instance, a page, user, or piece of media on a website may have existed at one point but was since deleted, but still has a permalink floating around the net.…

The article is fairly specific:

The first example: - no stack trace - loosing the specifics of error to troubleshoot.

The second example: - explicitly discards the stack trace - explicitly discards the error specifics.

Hence, if this is really what you want. fine, but in a lot of cases you do want to see stack traces and the exact reasons (and meta data why an error was thrown).

Re: You’re better off using Exceptions

#177
post #25

Exceptions in Haskell are unavoidable and awful. If you want to write code that responds to the errors that could occur, even some of them, you basically have to read the library source because they're completely undocumented in many libraries - even in the standard library (try something exotic like, um, reading a file). And that means you need to know your whole stack. If they were at least declared in the type so…

That does suck, does it commonly occur because of non-total functions in the libraries or what?

Re: You’re better off using Exceptions

#178
post #132

Earlier quoted context omitted.

Isn't that "forcing a developer to handle error conditions" only true of Java-style checked exceptions, though? I'm not aware of any non-JVM languages taking that route, even the very Java-clone-y C#, and thought it was widely believed to have been a mistake.

Unchecked exceptions are a disaster. In C# when you call a method you have no idea what exceptions can be thrown by the called method unless you inspect the called method and all the methods called by it. The called method can be modified at any time and a new exception can be thrown and your code will compile just fine. This is bad because the new exception may be a recoverable condition and instead of recovering yo…

As my opinions on exceptions have evolved throughout the years, I've come to think that there is value to unchecked exceptions, but unchecked exceptions need a fundamentally different mode from checked exceptions.

The best motivation for unchecked exceptions are things like division by 0, or null pointer dereferences: these are things that result from programmers misusing the API, and are generally unrecoverable. What you want instead is some sort of "graceful crash"--for example, if you're a web server, display a 500 page and log the stack trace somewhere internally. Using a pretty distinct mechanism for driving these error cases (e.g., Rust's panic mechanism) I think works better for emphasizing the crash aspect here.

Of course, now you have the regular checked exceptions which are a fundamental part of the function type. It's not clear to me that the try/catch/throw model is necessarily the best model for propagating these exceptions, and there are several cases where the overhead involved in the (misleadingly named) zero-cost exception handling model are not appropriate for the model.

Although there is something to be said for easy upgrading of checked into unchecked exceptions. It's a relatively natural assertion that something can't fail for reasons the compiler doesn't understand (which means informing the programmer when and where it failed is very critical!). I've always been annoyed by Eclipse deciding that the default implementation of catch should be "ignore the exception" instead of "wrap it in a RuntimeException."

Re: You’re better off using Exceptions

#179
post #99

Earlier quoted context omitted.

> Exceptions are a hell of a lot better than littering your code with null checks or error code checks, especially when you forget one and get a null pointer error or your code wanders away from the root cause and fails later. That's basically limitation of the language. Null checks and result checking can basically be abstracted away with non-nullable types, option types, and result types and bind. You only need to…

Result types are exceptions with different performance characteristics. Like, handling a checked exception (Java) and a Google-cpp StatusOr or a rust Result provide extraordinary similar code. Unchecked exceptions provide a bit of extra dynamism, and languages without either are anti-user.

I find result and option types compose nicer using monadic style composition.

Re: You’re better off using Exceptions

#180
post #29

I’d say this works in Erlang because it is part of the culture, but in java or python what I’ve seen mostly is people forgetting to catch exceptions, or not being able to pinpoint where exceptions are catched.

Erlang has a very different execution model compared to those other languages you mentioned. In fact, Erlang's culture in many ways encouraged to program less defensively than you would be expected to in other languages (ever heard of "let it crash"?).

That's because the whole expectation of exceptions/errors is built into the system unlike pretty much anywhere else.

Post reply on HN