C++ to Rust -- Exceptions
⚓ Rust 📅 2026-04-24 👤 surdeus 👁️ 2C++ Exceptions
One underappreciated feature of C++ is the ability to throw/catch exceptions. If one leverages the flexability of using different classes to represent different use-cases of 'exceptional behavior' a robust, readble, and extensible error handling system can be created and maintained.
A best practice is to create classes of exception that will capture as much infomation about the cause of the exception before the actual 'throw' and to use that to provide the user or higher level developer with a more meaningful error message.
try {
MyObj.myOperation()
}
catch ( const FileNotFound& e ) {
}
catch ( const IllegalConfigurationException& e ) {
}
catch ( const SyntaxException& e ) {
}
catch (const std::exception& e) {
}
catch (...) {
}
Rust
Rust, on the other hand, eschews exceptions. However, there is a feature in Rust that can be leveraged to create a similar pattern for error handling and provide much of the same of the same benefits using enums and the sugary '?' operator.
Enums
enum ErrorCases {
FileNotFound(String), // provide expected path of the missing file
IllegalConfiguration,
SyntaxError(u32/*line*/, u32/*column*/, String/*file*/),
Other(String),
}
fn my_file_operation(throw: bool) -> Result<(), ErrorCases> {
if throw { Err(ErrorCases::FileNotFound("my_file.txt".to_string())) } else { Ok(()) }
}
fn my_syntax_error(throw: bool) -> Result<(), ErrorCases> {
if throw { Err(ErrorCases::SyntaxError(10, 20, "my_file.txt".to_string())) } else { Ok(()) }
}
fn my_config_operation(throw: bool) -> Result<(), ErrorCases> {
if throw { Err(ErrorCases::IllegalConfiguration) } else { Ok(()) }
}
fn my_other_operation(throw: bool) -> Result<(), ErrorCases> {
if throw { Err(ErrorCases::Other("Unexpected error".to_string())) } else { Ok(()) }
}
fn my_operation() -> Result<(), ErrorCases> {
my_file_operation(false)?;
my_syntax_error(true)?;
my_config_operation(false)?;
my_other_operation(false)?;
Ok(())
}
fn main() {
match my_operation() {
Ok(_) => println!("Success"),
Err(ErrorCases::FileNotFound(path)) => println!("File not found: {path}"),
Err(ErrorCases::IllegalConfiguration) => println!("Illegal configuration"),
Err(ErrorCases::SyntaxError(line, column, file)) => println!("Syntax error on line {line} column {column} in file {file}"),
Err(ErrorCases::Other(msg)) => println!("Other error: {msg}"),
} ;
}
This can also ensure thorough error handling. Introducing a new error case will trigger the compiler to warn that the error needs to be handled. Provided of course that we do not use the 'wildcard' pattern to catch unknowns.
1 post - 1 participant
🏷️ Rust_feed