DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Porting GPU Drivers to Rust on ARM64: The Hardest Trial for Kernel-Level Computing
  • Rust-Native Alternatives to Spark SQL and DataFrame Workloads
  • KV Cache Implementation Inside vLLM
  • Imprisoning the Panic

Trending

  • Giving AI Agents Safe Access to Legacy Systems: Introducing legacy2mcp
  • Rebuilding Elasticsearch Under Load: Unsafe Watermarks and a Sampling Blind Spot
  • When RabbitMQ Accepts a Message but Does Not Route It to a Queue
  • One Database, Two Models: Building AI-Friendly Java Applications With MySQL JSON Duality Views

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Languages
  4. The Try Block in Rust

The Try Block in Rust

I wrote previously about libs for error management in Rust. This week, I want to write about the try block, an experimental feature.

By 
Nicolas Fränkel
·
Apr. 25, 24 · Analysis
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
1.9K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

I wrote previously about libs for error management in Rust. This week, I want to write about the try block, an experimental feature.

The Limit of The ? Operator

Please check the above article for a complete refresher on error management in general and the ? operator in particular. In short, ? allows to hook into a function call that returns a Result:

  • If the Result contains a value, it continues normally
  • If it contains an error, it short-circuits and returns the Result to the calling function.
Rust
 
fn add(str1: &str, str2: &str) -> Result<i8, ParseIntError> {
  Ok(str1.parse::<i8>()? + str2.parse::<i8>()?)
}

fn main() {
    print!("{:?}", add("1", "2"));
    print!("{:?}", add("1", "a"));
}


The output is the following:

Plain Text
 
Ok(3)
Err(ParseIntError { kind: InvalidDigit })


Note that the defining function's signature must return a Result or an Option. The following block doesn't compile:

Rust
 
fn add(str1: &str, str2: &str) -> i8 {
  str1.parse::<i8>()? + str2.parse::<i8>()?
}


Plain Text
 
the `?` operator can only be used in a function that returns `Result` or `Option`


The Verbose Alternative

We must manually unwrap to return a non-wrapper type, e.g., i8 instead of Option.

Rust
 
fn add(str1: &str, str2: &str) -> i8 {
  let int1 = str1.parse::<i8>();                  //1
  let int2 = str2.parse::<i8>();                  //1
  if int1.is_err() || int2.is_err() { -1 }        //2-3
  else { int1.unwrap() + int2.unwrap() }          //4
}


  1. Define Result variables
  2. Manually checks if any of the variables contains an error, i.e., the parsing failed
  3. Return a default value since we cannot get a Result. In this case, it's not a great idea, but it's for explanation's sake
  4. Unwrap with confidence

The try Block to the Rescue

The sample above works but is quite lengthy. The try block is an experimental approach to make it more elegant. It allows "compacting" all the checks for errors in a single block:

Rust
 
#![feature(try_blocks)]                           //1

fn add(str1: &str, str2: &str) -> i8 {
  let result = try {
    let int1 = str1.parse::<i8>();
    let int2 = str2.parse::<i8>();
    int1.unwrap()? + int2.unwrap()?               //2
  };
  if result.is_err() { -1 }                       //3
  else { result.unwrap() }                        //4
}


  1. Enable the experimental feature
  2. Use the ? operator though the defining function doesn't return Result
  3. Check for errors only once
  4. Unwrap confidently

Alas, the code doesn't compile:

Plain Text
 
the `?` operator can only be applied to values that implement `Try`


i8 doesn't implement Try. Neither i8 nor Try belong to our crate; a custom implementation would require the use of the wrapper-type pattern. Fortunately, a couple of types already implement Try: Result, Option, Poll, and ControlFlow.

Rust
 
fn add(str1: &str, str2: &str) -> i8 {
  let result: Result<i8, ParseIntError> = try {   //1
    str1.parse::<i8>()? + str2.parse::<i8>()?     //2
  };
  if result.is_err() { -1 }
  else { result.unwrap() }
}


  1. The compiler cannot infer the type
  2. Using ? on Result inside the try block is now allowed

try block

Conclusion

I learned about the try block in Java over twenty years ago. Java needs it because exceptions are at the root of its error-handling system; Rust doesn't because it uses Functional Programming for its error handling — mainly Result.

The ? operator builds upon the Result type to allow short-circuiting in functions that return Result themselves. If the function doesn't, you need a lot of boilerplate code. The experimental try block relieves some of it.

To Go Further

  • Error management in Rust, and libs that support it
  • "The Rust Unstable Book: try_blocks"
  • The Rust RFC Book
  • Extending Rust's Effect System
Functional programming Blocks Rust (programming language)

Published at DZone with permission of Nicolas Fränkel. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Porting GPU Drivers to Rust on ARM64: The Hardest Trial for Kernel-Level Computing
  • Rust-Native Alternatives to Spark SQL and DataFrame Workloads
  • KV Cache Implementation Inside vLLM
  • Imprisoning the Panic

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook