1+ #![ unstable( feature = "core_io_error_kind" , issue = "154046" ) ]
2+
3+ use crate :: fmt;
4+
5+ /// A list specifying general categories of I/O error.
6+ ///
7+ /// This list is intended to grow over time and it is not recommended to
8+ /// exhaustively match against it.
9+ ///
10+ /// # Handling errors and matching on `ErrorKind`
11+ ///
12+ /// In application code, use `match` for the `ErrorKind` values you are
13+ /// expecting; use `_` to match "all other errors".
14+ ///
15+ /// In comprehensive and thorough tests that want to verify that a test doesn't
16+ /// return any known incorrect error kind, you may want to cut-and-paste the
17+ /// current full list of errors from here into your test code, and then match
18+ /// `_` as the correct case. This seems counterintuitive, but it will make your
19+ /// tests more robust. In particular, if you want to verify that your code does
20+ /// produce an unrecognized error kind, the robust solution is to check for all
21+ /// the recognized error kinds and fail in those cases.
22+ #[ derive( Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
23+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
24+ #[ cfg_attr( not( test) , rustc_diagnostic_item = "io_errorkind" ) ]
25+ #[ allow( deprecated) ]
26+ #[ non_exhaustive]
27+ pub enum ErrorKind {
28+ /// An entity was not found, often a file.
29+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
30+ NotFound ,
31+ /// The operation lacked the necessary privileges to complete.
32+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
33+ PermissionDenied ,
34+ /// The connection was refused by the remote server.
35+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
36+ ConnectionRefused ,
37+ /// The connection was reset by the remote server.
38+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
39+ ConnectionReset ,
40+ /// The remote host is not reachable.
41+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
42+ HostUnreachable ,
43+ /// The network containing the remote host is not reachable.
44+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
45+ NetworkUnreachable ,
46+ /// The connection was aborted (terminated) by the remote server.
47+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
48+ ConnectionAborted ,
49+ /// The network operation failed because it was not connected yet.
50+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
51+ NotConnected ,
52+ /// A socket address could not be bound because the address is already in
53+ /// use elsewhere.
54+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
55+ AddrInUse ,
56+ /// A nonexistent interface was requested or the requested address was not
57+ /// local.
58+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
59+ AddrNotAvailable ,
60+ /// The system's networking is down.
61+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
62+ NetworkDown ,
63+ /// The operation failed because a pipe was closed.
64+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
65+ BrokenPipe ,
66+ /// An entity already exists, often a file.
67+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
68+ AlreadyExists ,
69+ /// The operation needs to block to complete, but the blocking operation was
70+ /// requested to not occur.
71+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
72+ WouldBlock ,
73+ /// A filesystem object is, unexpectedly, not a directory.
74+ ///
75+ /// For example, a filesystem path was specified where one of the intermediate directory
76+ /// components was, in fact, a plain file.
77+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
78+ NotADirectory ,
79+ /// The filesystem object is, unexpectedly, a directory.
80+ ///
81+ /// A directory was specified when a non-directory was expected.
82+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
83+ IsADirectory ,
84+ /// A non-empty directory was specified where an empty directory was expected.
85+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
86+ DirectoryNotEmpty ,
87+ /// The filesystem or storage medium is read-only, but a write operation was attempted.
88+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
89+ ReadOnlyFilesystem ,
90+ /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
91+ ///
92+ /// There was a loop (or excessively long chain) resolving a filesystem object
93+ /// or file IO object.
94+ ///
95+ /// On Unix this is usually the result of a symbolic link loop; or, of exceeding the
96+ /// system-specific limit on the depth of symlink traversal.
97+ #[ unstable( feature = "io_error_more" , issue = "86442" ) ]
98+ FilesystemLoop ,
99+ /// Stale network file handle.
100+ ///
101+ /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
102+ /// by problems with the network or server.
103+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
104+ StaleNetworkFileHandle ,
105+ /// A parameter was incorrect.
106+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
107+ InvalidInput ,
108+ /// Data not valid for the operation were encountered.
109+ ///
110+ /// Unlike [`InvalidInput`], this typically means that the operation
111+ /// parameters were valid, however the error was caused by malformed
112+ /// input data.
113+ ///
114+ /// For example, a function that reads a file into a string will error with
115+ /// `InvalidData` if the file's contents are not valid UTF-8.
116+ ///
117+ /// [`InvalidInput`]: ErrorKind::InvalidInput
118+ #[ stable( feature = "io_invalid_data" , since = "1.2.0" ) ]
119+ InvalidData ,
120+ /// The I/O operation's timeout expired, causing it to be canceled.
121+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
122+ TimedOut ,
123+ /// An error returned when an operation could not be completed because a
124+ /// call to an underlying writer returned [`Ok(0)`].
125+ ///
126+ /// This typically means that an operation could only succeed if it wrote a
127+ /// particular number of bytes but only a smaller number of bytes could be
128+ /// written.
129+ ///
130+ /// [`Ok(0)`]: Ok
131+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
132+ WriteZero ,
133+ /// The underlying storage (typically, a filesystem) is full.
134+ ///
135+ /// This does not include out of quota errors.
136+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
137+ StorageFull ,
138+ /// Seek on unseekable file.
139+ ///
140+ /// Seeking was attempted on an open file handle which is not suitable for seeking - for
141+ /// example, on Unix, a named pipe opened with `File::open`.
142+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
143+ NotSeekable ,
144+ /// Filesystem quota or some other kind of quota was exceeded.
145+ #[ stable( feature = "io_error_quota_exceeded" , since = "1.85.0" ) ]
146+ QuotaExceeded ,
147+ /// File larger than allowed or supported.
148+ ///
149+ /// This might arise from a hard limit of the underlying filesystem or file access API, or from
150+ /// an administratively imposed resource limitation. Simple disk full, and out of quota, have
151+ /// their own errors.
152+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
153+ FileTooLarge ,
154+ /// Resource is busy.
155+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
156+ ResourceBusy ,
157+ /// Executable file is busy.
158+ ///
159+ /// An attempt was made to write to a file which is also in use as a running program. (Not all
160+ /// operating systems detect this situation.)
161+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
162+ ExecutableFileBusy ,
163+ /// Deadlock (avoided).
164+ ///
165+ /// A file locking operation would result in deadlock. This situation is typically detected, if
166+ /// at all, on a best-effort basis.
167+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
168+ Deadlock ,
169+ /// Cross-device or cross-filesystem (hard) link or rename.
170+ #[ stable( feature = "io_error_crosses_devices" , since = "1.85.0" ) ]
171+ CrossesDevices ,
172+ /// Too many (hard) links to the same filesystem object.
173+ ///
174+ /// The filesystem does not support making so many hardlinks to the same file.
175+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
176+ TooManyLinks ,
177+ /// A filename was invalid.
178+ ///
179+ /// This error can also occur if a length limit for a name was exceeded.
180+ #[ stable( feature = "io_error_invalid_filename" , since = "1.87.0" ) ]
181+ InvalidFilename ,
182+ /// Program argument list too long.
183+ ///
184+ /// When trying to run an external program, a system or process limit on the size of the
185+ /// arguments would have been exceeded.
186+ #[ stable( feature = "io_error_a_bit_more" , since = "1.83.0" ) ]
187+ ArgumentListTooLong ,
188+ /// This operation was interrupted.
189+ ///
190+ /// Interrupted operations can typically be retried.
191+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
192+ Interrupted ,
193+
194+ /// This operation is unsupported on this platform.
195+ ///
196+ /// This means that the operation can never succeed.
197+ #[ stable( feature = "unsupported_error" , since = "1.53.0" ) ]
198+ Unsupported ,
199+
200+ // ErrorKinds which are primarily categorisations for OS error
201+ // codes should be added above.
202+ //
203+ /// An error returned when an operation could not be completed because an
204+ /// "end of file" was reached prematurely.
205+ ///
206+ /// This typically means that an operation could only succeed if it read a
207+ /// particular number of bytes but only a smaller number of bytes could be
208+ /// read.
209+ #[ stable( feature = "read_exact" , since = "1.6.0" ) ]
210+ UnexpectedEof ,
211+
212+ /// An operation could not be completed, because it failed
213+ /// to allocate enough memory.
214+ #[ stable( feature = "out_of_memory_error" , since = "1.54.0" ) ]
215+ OutOfMemory ,
216+
217+ /// The operation was partially successful and needs to be checked
218+ /// later on due to not blocking.
219+ #[ unstable( feature = "io_error_inprogress" , issue = "130840" ) ]
220+ InProgress ,
221+
222+ // "Unusual" error kinds which do not correspond simply to (sets
223+ // of) OS error codes, should be added just above this comment.
224+ // `Other` and `Uncategorized` should remain at the end:
225+ //
226+ /// A custom error that does not fall under any other I/O error kind.
227+ ///
228+ /// This can be used to construct your own errors that do not match any
229+ /// [`ErrorKind`].
230+ ///
231+ /// This [`ErrorKind`] is not used by the standard library.
232+ ///
233+ /// Errors from the standard library that do not fall under any of the I/O
234+ /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
235+ /// New [`ErrorKind`]s might be added in the future for some of those.
236+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
237+ Other ,
238+
239+ /// Any I/O error from the standard library that's not part of this list.
240+ ///
241+ /// Errors that are `Uncategorized` now may move to a different or a new
242+ /// [`ErrorKind`] variant in the future. It is not recommended to match
243+ /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
244+ #[ unstable( feature = "io_error_uncategorized" , issue = "none" ) ]
245+ #[ doc( hidden) ]
246+ Uncategorized ,
247+ }
248+
249+ impl ErrorKind {
250+ pub ( crate ) const fn as_str ( & self ) -> & ' static str {
251+ use ErrorKind :: * ;
252+ match * self {
253+ // tidy-alphabetical-start
254+ AddrInUse => "address in use" ,
255+ AddrNotAvailable => "address not available" ,
256+ AlreadyExists => "entity already exists" ,
257+ ArgumentListTooLong => "argument list too long" ,
258+ BrokenPipe => "broken pipe" ,
259+ ConnectionAborted => "connection aborted" ,
260+ ConnectionRefused => "connection refused" ,
261+ ConnectionReset => "connection reset" ,
262+ CrossesDevices => "cross-device link or rename" ,
263+ Deadlock => "deadlock" ,
264+ DirectoryNotEmpty => "directory not empty" ,
265+ ExecutableFileBusy => "executable file busy" ,
266+ FileTooLarge => "file too large" ,
267+ FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)" ,
268+ HostUnreachable => "host unreachable" ,
269+ InProgress => "in progress" ,
270+ Interrupted => "operation interrupted" ,
271+ InvalidData => "invalid data" ,
272+ InvalidFilename => "invalid filename" ,
273+ InvalidInput => "invalid input parameter" ,
274+ IsADirectory => "is a directory" ,
275+ NetworkDown => "network down" ,
276+ NetworkUnreachable => "network unreachable" ,
277+ NotADirectory => "not a directory" ,
278+ NotConnected => "not connected" ,
279+ NotFound => "entity not found" ,
280+ NotSeekable => "seek on unseekable file" ,
281+ Other => "other error" ,
282+ OutOfMemory => "out of memory" ,
283+ PermissionDenied => "permission denied" ,
284+ QuotaExceeded => "quota exceeded" ,
285+ ReadOnlyFilesystem => "read-only filesystem or storage medium" ,
286+ ResourceBusy => "resource busy" ,
287+ StaleNetworkFileHandle => "stale network file handle" ,
288+ StorageFull => "no storage space" ,
289+ TimedOut => "timed out" ,
290+ TooManyLinks => "too many links" ,
291+ Uncategorized => "uncategorized error" ,
292+ UnexpectedEof => "unexpected end of file" ,
293+ Unsupported => "unsupported" ,
294+ WouldBlock => "operation would block" ,
295+ WriteZero => "write zero" ,
296+ // tidy-alphabetical-end
297+ }
298+ }
299+ }
300+
301+ #[ stable( feature = "io_errorkind_display" , since = "1.60.0" ) ]
302+ impl fmt:: Display for ErrorKind {
303+ /// Shows a human-readable description of the `ErrorKind`.
304+ fn fmt ( & self , fmt : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
305+ fmt. write_str ( self . as_str ( ) )
306+ }
307+ }
0 commit comments