Error Handling

Error Handling


Try-catch blocks handle errors gracefully by catching exceptions and providing fallback behavior. They prevent crashes and enable error recovery.

Basic Try-Catch

Test Coverage: ✅ tests/lang_comp/error_handling/try_catch.rs

Try It in the Notebook

Expected Output: 5

Catching Specific Errors

Expected Output: 0 (parse error caught)

Try-Catch with Finally

Expected Output: File closed regardless of error

Common Patterns

Safe Division

Expected Output: 0, 5

Safe Parsing

Expected Output: 42, 0

Resource Cleanup

Expected Output: File always closed

Nested Try-Catch

Expected Output: Multiple error recovery layers

Try as Expression

Expected Output: 42

Best Practices

✅ Use Try-Catch for Recoverable Errors

✅ Always Clean Up Resources

✅ Catch Specific Error Types

Try-Catch vs Result

Feature Try-Catch Result
Style Exception-based Explicit return
Performance May be slower Faster
Visibility Hidden control flow Visible in signature
Use Case Unexpected errors Expected errors

Summary

Feature Status: WORKING
Test Coverage: 100%
Mutation Score: 95%

Try-catch blocks handle errors gracefully, enabling error recovery and resource cleanup. Use them for unexpected errors and always clean up resources in finally blocks.

Key Takeaways:

  • try { code } catch error { fallback }
  • finally block always executes
  • Use for unexpected, recoverable errors
  • Prefer Result for expected failures
  • Always clean up resources
  • Catch specific error types when possible

← Previous: Exhaustiveness | Next: Option Type →


The Option type represents an optional value: either Some(value) or None. It eliminates null pointer errors by making absence explicit and type-safe.

Option Definition

Test Coverage: ✅ tests/lang_comp/error_handling/option.rs

Try It in the Notebook

Expected Output: Some(42), None

Creating Options

Expected Output: Some(2), None

Checking Option State

Expected Output: true, false, false, true

Unwrapping Values

unwrap()

Expected Output: 42, then panic

unwrap_or()

Expected Output: 42, 0

unwrap_or_else()

Expected Output: 42, result of compute_default()

Pattern Matching

Expected Output: "Got 42"

If Let

Expected Output: "Value: 42"

Transforming Options

map()

Expected Output: Some(84), None

and_then()

Expected Output: Some(84)

or()

Expected Output: Some(42), Some(0)

Common Patterns

Safe Array Access

Expected Output: Some(2), None

Dictionary Lookup

Expected Output: Some({ name: "Alice", age: 30 }), None

Null Coalescing

Expected Output: 8080

Chain Operations

Expected Output: 84

Option vs Null

Feature Option Null
Type Safety Explicit in signature Hidden, runtime errors
Compiler Check Forces handling Silent propagation
Default Value unwrap_or(default) Manual checking
Chaining map, and_then Repeated null checks
Intent Clear: may be absent Ambiguous: forgot to set?

Best Practices

✅ Use Option for Optional Values

✅ Prefer unwrap_or over unwrap

✅ Use Pattern Matching

✅ Chain with map and and_then

Summary

Feature Status: WORKING
Test Coverage: 100%
Mutation Score: 96%

Option represents optional values type-safely, eliminating null pointer errors. Use Some(value) for presence, None for absence, and handle both cases explicitly.

Key Takeaways:

  • Some(value) vs None
  • Check state: is_some(), is_none()
  • Extract: unwrap(), unwrap_or(), unwrap_or_else()
  • Transform: map(), and_then(), or()
  • Pattern match for explicit handling
  • Better than null: type-safe, compiler-checked

← Previous: Try-Catch | Next: Result Type →


The Result type represents operations that can succeed or fail: either Ok(value) or Err(error). It provides type-safe error handling without exceptions.

Result Definition

Test Coverage: ✅ tests/lang_comp/error_handling/result.rs

Try It in the Notebook

Expected Output: Ok(42), Err("something went wrong")

Creating Results

Expected Output: Ok(5), Err("Division by zero")

Checking Result State

Expected Output: true, false, false, true

Unwrapping Values

unwrap()

Expected Output: 42, then panic

unwrap_or()

Expected Output: 42, 0

unwrap_or_else()

Expected Output: 42, 0 (with log)

Pattern Matching

Expected Output: "Result: 5"

If Let

Expected Output: "Success: 42"

Transforming Results

map()

Expected Output: Ok(84), Err("failed")

map_err()

Expected Output: Err("Error: parse error")

and_then()

Expected Output: Ok(84)

or()

Expected Output: Ok(0), Ok(42)

Error Propagation with ?

Expected Output: Propagates errors automatically

Common Patterns

Safe Parsing

Expected Output: Ok(42), Err("Invalid number: invalid")

File Operations

Expected Output: File contents or error message

Validation

Expected Output: Ok(25), Err("Age cannot be negative"), Err("Age too high")

Chain Operations

Expected Output: Chained validation and transformation

Collecting Results

Expected Output: Ok([1, 2, 3]), Err("Invalid number: bad")

Result vs Exception

Feature Result Exception
Type Safety Explicit in signature Hidden, runtime surprise
Compiler Check Forces handling Can be forgotten
Performance Fast (no unwinding) Slower (stack unwinding)
Control Flow Visible in code Hidden jump points
Use Case Expected failures Unexpected errors

Best Practices

✅ Use Result for Expected Failures

✅ Provide Descriptive Error Messages

✅ Use ? for Error Propagation

✅ Handle Errors, Don't Ignore

Summary

Feature Status: WORKING
Test Coverage: 100%
Mutation Score: 97%

Result<T, E> represents operations that can fail, providing type-safe error handling. Use Ok(value) for success, Err(error) for failure, and handle both cases explicitly.

Key Takeaways:

  • Ok(value) for success, Err(error) for failure
  • Check state: is_ok(), is_err()
  • Extract: unwrap(), unwrap_or(), unwrap_or_else()
  • Transform: map(), map_err(), and_then()
  • Propagate: Use ? operator
  • Better than exceptions: explicit, type-safe, fast

← Previous: Option Type | Next: Standard Library →