Live data from Hacker News

Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

msirringhaus.github.io

51–60 of 204 posts

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#51
post #9

Earlier quoted context omitted.

The only system I think should completely go is Exceptions except in the case of termination or absolutely catastrophic failure - this isn't really about programming but rather that the implementation is a total pain, the compiler struggles to optimize them, and even better they make quite a few safety analyses like borrow checking very difficult because the control flow graph basically explodes when you start consid…

In terms of control flow, this: try { someCall(); } catch (ErrorICanHandle err) { //handle } perfectly equivalent to this: err = someCall(); if canHandle(err) { //do something } else { return err } I don't see why so many people think exceptions make code harder to analyze. In my opinion, it is errors themselves that make code hard to analyze, regardless of implementation strategy. The only difference between excepti…

this issue is knowing whether you are catching the right errors

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#52

Error handling has been wrong since the beginning, and has continued to be wrong ever since. First, we had error codes. Except these were wrong because people forget all the time to check them. Then we had exceptions, which solved the problem of people forgetting to check by crashing the app. Then the Java team got the bright idea to have checked exceptions, which at first helped to mitigate crashes from uncaught exc…

> Error handling has been wrong since the beginning 100% this. The very concept of "error" is philosophically unsound. There are no errors; only conditions that you dislike. It is unfortunate that programming languages allow to express your emotional detachment to one of both cases of a branch. Nothing good can come from that. I yearn for a language with no error handling nor exceptions. Just plain language construct…

Aye. throw/raise is GOTO.

Forth?

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#53

Earlier quoted context omitted.

> Error handling has been wrong since the beginning 100% this. The very concept of "error" is philosophically unsound. There are no errors; only conditions that you dislike. It is unfortunate that programming languages allow to express your emotional detachment to one of both cases of a branch. Nothing good can come from that. I yearn for a language with no error handling nor exceptions. Just plain language construct…

Aye. throw/raise is GOTO. Forth?

> throw/raise is GOTO.

Worse, it's COME FROM!

https://en.wikipedia.org/wiki/COMEFROM

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#54
post #10
post #3

Earlier quoted context omitted.

Rust error handling is great for reliable systems. But it used to be really annoying when just doing exploratory coding. With the anyhow crate, this problem is solved as well. Just use anyhow if you just want to try something out quickly without being slowed down by error type mismatches, and then later refine it to a handcrafted error type. I prefer rust error handling over all other languages I worked with (scala,…

Completely agree. I used to create my own error type(s) manually and implement the various conversions for 3rd party crates and it was quite a lot of boilerplate but with anyhow (for applications where you don't really care about strict error types) and thiserror (when you need to be a little more thorough). Actually that's effectively TFA's solution, if they had used thiserror/anyhow from the start there might not h…

This is really interesting because I recently found the anyhow crate and I was wondering why it's not mentioned anywhere else. Definitely feels like useful information that a newly minted Rust dev could make use of.

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#55
post #17

Someday I will attempt to use some rust software from the internet without almost immediately running into a panic with some inscrutable message. Maybe that day will be a day after _f$#$@@#$_ _crashing_ stops being the easiest and most idiomatic way of handling unexpected conditions.

I prefer it when a program just gives up and crashes when it encounters an unexpected condition, instead of trying to soldier on and later possibly corrupting some data or state I care about, because it was working under incorrect assumptions.

Now, the amount of unexpected conditions should be kept to a minimum, essentially just things outside of control of that program that the program cannot verify reliably. The rest should be _expected_ conditions, and error-handled properly.

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#56

Error handling has been wrong since the beginning, and has continued to be wrong ever since. First, we had error codes. Except these were wrong because people forget all the time to check them. Then we had exceptions, which solved the problem of people forgetting to check by crashing the app. Then the Java team got the bright idea to have checked exceptions, which at first helped to mitigate crashes from uncaught exc…

I think that exceptions are a problem and cause this developer burden only because they are invisible. If they appeared in the type signature, for example as

() -[DatabaseReadError]-> ()

then they would be part of a function's 'contract'.

With this, consumers of your function are making an active decision about whether to handle or bubble an exception without examining your implementation, and the type of the main function tells you which errors will end up being fatal.

Disclaimer: this is not a new idea. There are proposals for OCaml to add 'algebraic effects', which have similar annotations on arrows, and I believe there have been discussions around using the syntax to track exceptions.

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#57

Error handling has been wrong since the beginning, and has continued to be wrong ever since. First, we had error codes. Except these were wrong because people forget all the time to check them. Then we had exceptions, which solved the problem of people forgetting to check by crashing the app. Then the Java team got the bright idea to have checked exceptions, which at first helped to mitigate crashes from uncaught exc…

I think that exceptions are a problem and cause this developer burden only because they are invisible. If they appeared in the type signature, for example as () -[DatabaseReadError]-> () then they would be part of a function's 'contract'. With this, consumers of your function are making an active decision about whether to handle or bubble an exception without examining your implementation, and the type of the main fu…

The biggest problem with that is that it is very unwieldly if you're using any kind of higher-order functions.

To fix that, you need to start supporting error polymorphism. For example, `map` should have a signature like

  map :: List a -> (a -> b -[err]) -> List b -[err]
So that

  map [1 2 3] +1 //no errors
  map [1 2 3] sendOnNetwork //returns NetworkError
At least, this is one of the major limitation of Java's Checked Exceptions idea, one which often forces you to use Unchecked Exceptions.

Another common problem is handling exceptions which occur while handling another exception. D has the best default I've seen in that area (it will automatically collect all of the errors, instead of panic()-ing like C++ or discarding the old exception like Java and C#).

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#58

Earlier quoted context omitted.

Aye. throw/raise is GOTO. Forth?

> throw/raise is GOTO. Worse, it's COME FROM! https://en.wikipedia.org/wiki/COMEFROM

To be fair, throw is GOTO. Catch() is COMEFROM :).

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#59
post #17

Someday I will attempt to use some rust software from the internet without almost immediately running into a panic with some inscrutable message. Maybe that day will be a day after _f$#$@@#$_ _crashing_ stops being the easiest and most idiomatic way of handling unexpected conditions.

Curious: which Rust software that you immediately ran into panic with?

Re: Where Everything Went Wrong: Error Handling and Error Messages in Rust (2020)

#60

Error handling has been wrong since the beginning, and has continued to be wrong ever since. First, we had error codes. Except these were wrong because people forget all the time to check them. Then we had exceptions, which solved the problem of people forgetting to check by crashing the app. Then the Java team got the bright idea to have checked exceptions, which at first helped to mitigate crashes from uncaught exc…

> Error handling has been wrong since the beginning 100% this. The very concept of "error" is philosophically unsound. There are no errors; only conditions that you dislike. It is unfortunate that programming languages allow to express your emotional detachment to one of both cases of a branch. Nothing good can come from that. I yearn for a language with no error handling nor exceptions. Just plain language construct…

Well, what you're saying is exactly the reason why java called them Exceptions and not Errors (well, Error also exists, but it is generally reserved for very nasty problems).

Anyway, you can't just define the problem away, or else you end up with Go style error handling - that is exactly what a language with no built-in support for errors looks like.

Languages need to offer control flow mechanisms that allow you to separate common cases in the code from the uncommon cases. Especially since for most code, the uncommon cases appear deep in the bowels of an application, and the only way to handle them is to ask an actual human to handle them, usually on the opposite side of the application stack.

For a more reified implementation of this pattern, the Common Lisp Condition system is very interesting. It is similar to most Exception systems (code can raise a Condition, at which point a handler for that Condition is searched for up the call stack), but with one crucial difference: when raising a Condition, you can also specify Restarts - alternatives for how to proceed. Condition handlers can choose whether to cancel the execution flow and handle the condition with their own logic, OR they can choose to invoke one of the Restarts offered along the condition, based on their own logic. An example would be something like: Raise ConfigFileNotFound; Restarts: ContinueWithDefaults, Retry, ContinueWithOtherFile(newFileName). Then, a Condition handler (possibly a User) can choose to stop the application, or it can choose to continue with the defaults, or it can create the file with its own defaults and Retry, or it can try a different config file path.

This offers a lot of flexibility and has uses outside the idea of handling errors.

Post reply on HN