Comparing error handling in Java, Go and Rust.

legolord208

jD91mZM2

Posted on July 4, 2017

Comparing error handling in Java, Go and Rust.

Error checking is everywhere. Sometimes it's more complex than other time. Take file managing for example. You have to remember to close the file every time you return... If it's not automatic.

Let's see how Java does it. First, we'll look at Java 6-.

BufferedReader reader;
try {
    reader = new BufferedReader(new FileInputStream("test.txt"));
    // read file
    if (condition) {
        // closed by finally block
        return;
    }

    // closed by finally block
} catch(Exception e) {
    // do proper error handling
    // closed by finally block
} finally {
    try {
        reader.close();
    } catch(Exception e) {
        // do proper error handling
    }
}

System.out.println("File read");
Enter fullscreen mode Exit fullscreen mode

Oh my God. OK, that is HORRIBLE. Let's see how Java 7+ does.

try(BufferedReader reader = new BufferedReader(new FileInputStream("test.txt"))) {
    // read file
    if (condition) {
        // automatically closed
        return;
    }

    // automatically closed
} catch(Exception e) {
    // do proper error handling
    // automatically closed
}

System.out.println("File read")
Enter fullscreen mode Exit fullscreen mode

That is... very good. Congrats, Java. Let's see how Go does it.

file, err := os.Open("test.txt") // no semicolon :(
                                 // i love semicolons :(
if err != nil {
    // do proper error handling
}
defer file.Close()
// read file
if condition {
    // closed by defer
    return
}

fmt.Println("File read")
// File closed on return, so you probably wanna return ASAP
Enter fullscreen mode Exit fullscreen mode

One thing to note with Go: Independent error handling. You can't handle all errors clumped together. This is GOOD. This let's you specify where exactly it went wrong. Errors in Go are also pretty much strings. You make a custom error with errors.New("oh no"). Good stuff
Now let's take a look at Rust.

{ // Start a new scope. You don't *have* to do this
    let file = match File::open("test.txt") {
        Ok(file) => file,
        Err(err) => {
            // do proper error handling
            return;
        }
    };
    // read file
    if condition {
        // out of scope - automatically closed
        return;
    }

    // out of scope - automatically closed
}

println!("File read");
Enter fullscreen mode Exit fullscreen mode

After writing this, I had to look at the code again, thinking "that's it".
Like you can see, I clearly like Rust's the most. Java 7's is also good. Go's is good, but defer statements only execute on function end, not scope based. You can of course close it manually, but that sucks too.
On the other hand, Go error types are amazing to work with. errors.New("custom error") is amazing. Java's is not too bad, but Rust's is "worst" for us lazy people, but also the most powerful. Plus there are macros that fix this.

💖 💪 🙅 🚩
legolord208
jD91mZM2

Posted on July 4, 2017

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related