Hone logo
Hone
Problems

Robust File Processing with Error Handling in Rust

This challenge focuses on implementing robust error handling in Rust when processing a file. You'll write a program that attempts to read a file, parse its contents as integers, and calculate their sum. Proper error handling is crucial to prevent crashes and provide informative feedback to the user when things go wrong.

Problem Description

You are tasked with creating a Rust program that reads a file containing a list of integers, one integer per line. The program should attempt to read the file, parse each line into an integer, and calculate the sum of all the integers. The program must handle potential errors gracefully, providing informative error messages to the user instead of panicking.

Key Requirements:

  • File Reading: The program should open and read the specified file.
  • Line Parsing: Each line of the file should be parsed as an integer.
  • Sum Calculation: The program should calculate the sum of all successfully parsed integers.
  • Error Handling: The program must handle the following errors:
    • File Not Found: If the specified file does not exist.
    • IO Error: If there's an error reading the file (e.g., permission issues).
    • Parse Error: If a line in the file cannot be parsed as an integer (e.g., contains non-numeric characters).
  • Informative Error Messages: When an error occurs, the program should print a clear and informative error message to the console, indicating the type of error and, if possible, the line number where the error occurred.
  • Graceful Exit: The program should exit gracefully after encountering an error, without panicking.

Expected Behavior:

  1. The program should take a filename as a command-line argument.
  2. If the file exists and contains valid integers, the program should print the sum of the integers.
  3. If any error occurs during file reading or parsing, the program should print an appropriate error message and exit with a non-zero exit code (Rust's Result type will help with this).

Edge Cases to Consider:

  • Empty file: The program should handle an empty file gracefully (sum should be 0).
  • File with only invalid lines: The program should report all parsing errors and exit.
  • Very large files: While not a primary focus, consider how your solution might perform with large files.

Examples

Example 1:

Input: file.txt containing:
1
2
3
4
5

Output:

Sum: 15

Explanation: The program successfully reads the file, parses the integers, and calculates their sum.

Example 2:

Input: file.txt containing:
1
2
abc
4
5

Output:

Error: Could not parse line 3 as an integer: abc

Explanation: The program encounters a parsing error on line 3 ("abc"). It prints an error message and exits.

Example 3:

Input: non_existent_file.txt
Output:
Error: File not found: non_existent_file.txt

Explanation: The program attempts to open a file that does not exist and prints a "File not found" error.

Constraints

  • The filename will be provided as a command-line argument (a &str).
  • Each line in the file will be a string.
  • The integers in the file will be within the range of i32.
  • The program should compile and run without warnings.
  • The program should handle errors efficiently, avoiding unnecessary allocations or computations.

Notes

  • Rust's Result type is your friend! Use it to represent the success or failure of operations.
  • The std::fs module provides functions for file I/O.
  • The str::parse method can be used to parse strings into integers.
  • Consider using match or if let to handle the Result type effectively.
  • The std::process::exit function can be used to exit the program with a specific exit code. A non-zero exit code typically indicates an error.
  • Line numbers can be tracked using a counter within the reading loop.
Loading editor...
rust