I work for a company mostly using Java, but I choose to rewrite a preformance critical part of the system in Rust. Before this rewrite I had only written some smaller thing in Rust, so i was familiar with the language, but not very experienced. When I did the re-write I expected the performance increase, I was also impressed by the concurrency and the safety around that. It is of course still possible to deadlock, but most other issues around concurrency just goes away. I found that rust really lives up to the credo “fearless concurrency”. However, all of these things were expected.

One of the things I had a hard time adjusting to was all this Error handling that was required, and getting used to the ? operator, learning to use the thiserror crate. I initially thought that this was the weak point of Rust. After a while I learned to use it and realized that it was quite the opposite. When I learned how to do the error handling, I suddenly found that the result is that there are no surprise errors left in production.

The unexpected benefit I saw was that the logfiles have shrunk with a factor 100 from Java to Rust. In java there are so many things that might go wrong in so many ways, that you need to log the internal state all over the place to be able to understand why something blew up. In the rust version, I get a clean and handled error in my log stating exactly what went wrong. Being forced to handle errors, combined with great mechanisms to do it, is a under appreciated side of Rust.

What is your most surprising benefit of using Rust?

  • anlumo@feddit.de
    link
    fedilink
    English
    arrow-up
    5
    ·
    2 years ago

    I’m kinda surprised by that, since Java is the one language that actually requires you to declare exceptions your code can throw. Shouldn’t that be semantically be the same as a Result<T, E>?

    • snaggenOP
      link
      fedilink
      English
      arrow-up
      2
      ·
      2 years ago

      Well, but then any function may also throw random runtime exceptions, so even if a function declares that it throws IOException, it may also deep down throw an IllegalStateException. And if you then were naive enough to only catch IOException, then you are in trouble. I recently had that case, were I had forgot the top level catch (Throwable t) clause and the program just died with nothing in any log. Adding that top level catch and a log line, made me see where it threw and what. Then I just needed to add additional logging around that to see the application state to understand the why.

      • anlumo@feddit.de
        link
        fedilink
        English
        arrow-up
        5
        ·
        2 years ago

        A runtime exception is the equivalent of a panic in Rust, with the same issues.

        • snaggenOP
          link
          fedilink
          English
          arrow-up
          2
          ·
          2 years ago

          It should be, in the ideal world, just be thrown as a last resort… but in reality it isn’t. I assume it is because when you find a nice IllegalStateException, you might feel that it really describes your condition quite well, so you use that without realizing that it is a surprise exception since that is not very clear. When you are using your IDE and need to throw an exception in an error case, it is not clear what is a runtime exception and not, and then you are not forced to use throws and here we are…

          The equivalent in Rust would be to have a std::error::GenericError(String) in rust, that looks like a normal error but secretly panics under the hood.