I/O errors¶
IoError and FileError: the error vocabulary every io module answers.
Import¶
No program writes this import for the two enums. <io/contracts> re-exports this module,
and <io/fs> and <io/buf> re-export <io/contracts>, so any of those brings both names:
use <io/fs> # IoError and FileError ride along
<io/files> hands FileError on the same way. The module itself is importable, and
use <io/error> as ioe puts the two names behind a dot (ioe.IoError.NotFound).
Overview¶
Both are predefined enums -- the compiler synthesizes them, and no unit declares them --
and this module is their HOME. The import gates the bare name exactly as <net/error>
gates NetError and <collections/hashmap> gates HashMap; the re-export is what makes
the home reachable through the module whose calls answer the enum
(docs/design/unit-namespaces.md, section 8.1).
public enum IoError:
NotFound PermissionDenied AlreadyExists
IsDirectory DiskFull TooManyOpen
InvalidInput Interrupted TimedOut
ConnectionReset Closed Other
Os(i32)
IoError is the ONE channel every io contract method answers -- a read, a write, a
seek, open() and close(), on a File, a TcpStream or a buffered handle alike. A
contract carries one signature and has no Self, so a method cannot answer FileError
on a File and NetError on a TcpStream; the domain enums stay on construction,
addressing and options. Os(i32) carries an errno no other variant names.
public enum FileError:
NotFound PermissionDenied AlreadyExists
IsDirectory DiskFull TooManyOpen
InvalidPath IOError Other
FileError is what the path utilities (stat, walk, mkdir_all, remove_all,
exists, remove, read_dir) and the fd_* primitives answer.
The variant ORDER of each is the ABI: the index is the tag the descriptor layer stores into a Result payload, so a variant is only ever appended.
Functions¶
to_io() -> IoError¶
extend FileError to_io() IoError
Turns a file-system error into the one channel the io contracts answer. Every FileError
variant with no twin in IoError belongs to an open rather than to a read or a write, so
nothing a contract method can answer is lost; IOError has already thrown its errno
away and collapses to Other. The conversion runs INSIDE the stdlib -- open() is
fd_open with its error passed through to_io() -- and a program never needs to call it.
Example¶
use <io/fs>
use <io/buf>
fn first_line(string path) string | IoError:
let File f = open(path, FileMode.Read())??
let BufReader@(File) r = BufReader.new(nom f, 8192)??
return Result.Ok(r.read_line()??.realise(""))
fn main() i32:
match first_line("/etc/hosts"):
Result.Ok(line) -> println(line)
Result.Err(IoError.NotFound) -> println("no such file")
Result.Err(IoError.PermissionDenied) -> println("not allowed")
Result.Err(_) -> println("failed")
return Result.Ok(0)
See also¶
- I/O Contracts --
Reader,Writer,Seek: the methods that answerIoError - File-system ops --
File,open(), and the path utilities that answerFileError - Net errors --
NetError, the same shape for the net modules - Unit namespaces -- why a predefined enum has a home, and how a re-export reaches it