]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/error.rs
Rename ErrorKind::Unknown to Uncategorized.
[rust.git] / library / std / src / io / error.rs
1 #[cfg(test)]
2 mod tests;
3
4 use crate::convert::From;
5 use crate::error;
6 use crate::fmt;
7 use crate::result;
8 use crate::sys;
9
10 /// A specialized [`Result`] type for I/O operations.
11 ///
12 /// This type is broadly used across [`std::io`] for any operation which may
13 /// produce an error.
14 ///
15 /// This typedef is generally used to avoid writing out [`io::Error`] directly and
16 /// is otherwise a direct mapping to [`Result`].
17 ///
18 /// While usual Rust style is to import types directly, aliases of [`Result`]
19 /// often are not, to make it easier to distinguish between them. [`Result`] is
20 /// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias
21 /// will generally use `io::Result` instead of shadowing the [prelude]'s import
22 /// of [`std::result::Result`][`Result`].
23 ///
24 /// [`std::io`]: crate::io
25 /// [`io::Error`]: Error
26 /// [`Result`]: crate::result::Result
27 /// [prelude]: crate::prelude
28 ///
29 /// # Examples
30 ///
31 /// A convenience function that bubbles an `io::Result` to its caller:
32 ///
33 /// ```
34 /// use std::io;
35 ///
36 /// fn get_string() -> io::Result<String> {
37 ///     let mut buffer = String::new();
38 ///
39 ///     io::stdin().read_line(&mut buffer)?;
40 ///
41 ///     Ok(buffer)
42 /// }
43 /// ```
44 #[stable(feature = "rust1", since = "1.0.0")]
45 pub type Result<T> = result::Result<T, Error>;
46
47 /// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
48 /// associated traits.
49 ///
50 /// Errors mostly originate from the underlying OS, but custom instances of
51 /// `Error` can be created with crafted error messages and a particular value of
52 /// [`ErrorKind`].
53 ///
54 /// [`Read`]: crate::io::Read
55 /// [`Write`]: crate::io::Write
56 /// [`Seek`]: crate::io::Seek
57 #[stable(feature = "rust1", since = "1.0.0")]
58 pub struct Error {
59     repr: Repr,
60 }
61
62 #[stable(feature = "rust1", since = "1.0.0")]
63 impl fmt::Debug for Error {
64     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65         fmt::Debug::fmt(&self.repr, f)
66     }
67 }
68
69 enum Repr {
70     Os(i32),
71     Simple(ErrorKind),
72     // &str is a fat pointer, but &&str is a thin pointer.
73     SimpleMessage(ErrorKind, &'static &'static str),
74     Custom(Box<Custom>),
75 }
76
77 #[derive(Debug)]
78 struct Custom {
79     kind: ErrorKind,
80     error: Box<dyn error::Error + Send + Sync>,
81 }
82
83 /// A list specifying general categories of I/O error.
84 ///
85 /// This list is intended to grow over time and it is not recommended to
86 /// exhaustively match against it.
87 ///
88 /// It is used with the [`io::Error`] type.
89 ///
90 /// [`io::Error`]: Error
91 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
92 #[stable(feature = "rust1", since = "1.0.0")]
93 #[allow(deprecated)]
94 #[non_exhaustive]
95 pub enum ErrorKind {
96     /// An entity was not found, often a file.
97     #[stable(feature = "rust1", since = "1.0.0")]
98     NotFound,
99     /// The operation lacked the necessary privileges to complete.
100     #[stable(feature = "rust1", since = "1.0.0")]
101     PermissionDenied,
102     /// The connection was refused by the remote server.
103     #[stable(feature = "rust1", since = "1.0.0")]
104     ConnectionRefused,
105     /// The connection was reset by the remote server.
106     #[stable(feature = "rust1", since = "1.0.0")]
107     ConnectionReset,
108     /// The connection was aborted (terminated) by the remote server.
109     #[stable(feature = "rust1", since = "1.0.0")]
110     ConnectionAborted,
111     /// The network operation failed because it was not connected yet.
112     #[stable(feature = "rust1", since = "1.0.0")]
113     NotConnected,
114     /// A socket address could not be bound because the address is already in
115     /// use elsewhere.
116     #[stable(feature = "rust1", since = "1.0.0")]
117     AddrInUse,
118     /// A nonexistent interface was requested or the requested address was not
119     /// local.
120     #[stable(feature = "rust1", since = "1.0.0")]
121     AddrNotAvailable,
122     /// The operation failed because a pipe was closed.
123     #[stable(feature = "rust1", since = "1.0.0")]
124     BrokenPipe,
125     /// An entity already exists, often a file.
126     #[stable(feature = "rust1", since = "1.0.0")]
127     AlreadyExists,
128     /// The operation needs to block to complete, but the blocking operation was
129     /// requested to not occur.
130     #[stable(feature = "rust1", since = "1.0.0")]
131     WouldBlock,
132     /// A parameter was incorrect.
133     #[stable(feature = "rust1", since = "1.0.0")]
134     InvalidInput,
135     /// Data not valid for the operation were encountered.
136     ///
137     /// Unlike [`InvalidInput`], this typically means that the operation
138     /// parameters were valid, however the error was caused by malformed
139     /// input data.
140     ///
141     /// For example, a function that reads a file into a string will error with
142     /// `InvalidData` if the file's contents are not valid UTF-8.
143     ///
144     /// [`InvalidInput`]: ErrorKind::InvalidInput
145     #[stable(feature = "io_invalid_data", since = "1.2.0")]
146     InvalidData,
147     /// The I/O operation's timeout expired, causing it to be canceled.
148     #[stable(feature = "rust1", since = "1.0.0")]
149     TimedOut,
150     /// An error returned when an operation could not be completed because a
151     /// call to [`write`] returned [`Ok(0)`].
152     ///
153     /// This typically means that an operation could only succeed if it wrote a
154     /// particular number of bytes but only a smaller number of bytes could be
155     /// written.
156     ///
157     /// [`write`]: crate::io::Write::write
158     /// [`Ok(0)`]: Ok
159     #[stable(feature = "rust1", since = "1.0.0")]
160     WriteZero,
161     /// This operation was interrupted.
162     ///
163     /// Interrupted operations can typically be retried.
164     #[stable(feature = "rust1", since = "1.0.0")]
165     Interrupted,
166
167     /// An error returned when an operation could not be completed because an
168     /// "end of file" was reached prematurely.
169     ///
170     /// This typically means that an operation could only succeed if it read a
171     /// particular number of bytes but only a smaller number of bytes could be
172     /// read.
173     #[stable(feature = "read_exact", since = "1.6.0")]
174     UnexpectedEof,
175     /// A custom error that does not fall under any other I/O error kind.
176     ///
177     /// This can be used to construct your own [`Error`]s that do not match any
178     /// [`ErrorKind`].
179     ///
180     /// This [`ErrorKind`] is not used by the standard library.
181     ///
182     /// Errors from the standard library that do not fall under any of the I/O
183     /// error kinds cannot be `match`ed on, and will only match a wildcard (`_`) pattern.
184     /// New [`ErrorKind`]s might be added in the future for some of those.
185     #[stable(feature = "rust1", since = "1.0.0")]
186     Other,
187
188     /// This operation is unsupported on this platform.
189     ///
190     /// This means that the operation can never succeed.
191     #[stable(feature = "unsupported_error", since = "1.53.0")]
192     Unsupported,
193
194     /// An operation could not be completed, because it failed
195     /// to allocate enough memory.
196     #[stable(feature = "out_of_memory_error", since = "1.54.0")]
197     OutOfMemory,
198
199     /// Any I/O error from the standard library that's not part of this list.
200     ///
201     /// Errors that are `Uncategorized` now may move to a different or a new
202     /// [`ErrorKind`] variant in the future. It is not recommended to match
203     /// an error against `Uncategorized`; use a wildcard match (`_`) instead.
204     #[unstable(feature = "io_error_uncategorized", issue = "none")]
205     #[doc(hidden)]
206     Uncategorized,
207 }
208
209 impl ErrorKind {
210     pub(crate) fn as_str(&self) -> &'static str {
211         match *self {
212             ErrorKind::NotFound => "entity not found",
213             ErrorKind::PermissionDenied => "permission denied",
214             ErrorKind::ConnectionRefused => "connection refused",
215             ErrorKind::ConnectionReset => "connection reset",
216             ErrorKind::ConnectionAborted => "connection aborted",
217             ErrorKind::NotConnected => "not connected",
218             ErrorKind::AddrInUse => "address in use",
219             ErrorKind::AddrNotAvailable => "address not available",
220             ErrorKind::BrokenPipe => "broken pipe",
221             ErrorKind::AlreadyExists => "entity already exists",
222             ErrorKind::WouldBlock => "operation would block",
223             ErrorKind::InvalidInput => "invalid input parameter",
224             ErrorKind::InvalidData => "invalid data",
225             ErrorKind::TimedOut => "timed out",
226             ErrorKind::WriteZero => "write zero",
227             ErrorKind::Interrupted => "operation interrupted",
228             ErrorKind::UnexpectedEof => "unexpected end of file",
229             ErrorKind::Unsupported => "unsupported",
230             ErrorKind::OutOfMemory => "out of memory",
231             ErrorKind::Other => "other error",
232             ErrorKind::Uncategorized => "uncategorized error",
233         }
234     }
235 }
236
237 /// Intended for use for errors not exposed to the user, where allocating onto
238 /// the heap (for normal construction via Error::new) is too costly.
239 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
240 impl From<ErrorKind> for Error {
241     /// Converts an [`ErrorKind`] into an [`Error`].
242     ///
243     /// This conversion allocates a new error with a simple representation of error kind.
244     ///
245     /// # Examples
246     ///
247     /// ```
248     /// use std::io::{Error, ErrorKind};
249     ///
250     /// let not_found = ErrorKind::NotFound;
251     /// let error = Error::from(not_found);
252     /// assert_eq!("entity not found", format!("{}", error));
253     /// ```
254     #[inline]
255     fn from(kind: ErrorKind) -> Error {
256         Error { repr: Repr::Simple(kind) }
257     }
258 }
259
260 impl Error {
261     /// Creates a new I/O error from a known kind of error as well as an
262     /// arbitrary error payload.
263     ///
264     /// This function is used to generically create I/O errors which do not
265     /// originate from the OS itself. The `error` argument is an arbitrary
266     /// payload which will be contained in this [`Error`].
267     ///
268     /// # Examples
269     ///
270     /// ```
271     /// use std::io::{Error, ErrorKind};
272     ///
273     /// // errors can be created from strings
274     /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
275     ///
276     /// // errors can also be created from other errors
277     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
278     /// ```
279     #[stable(feature = "rust1", since = "1.0.0")]
280     pub fn new<E>(kind: ErrorKind, error: E) -> Error
281     where
282         E: Into<Box<dyn error::Error + Send + Sync>>,
283     {
284         Self::_new(kind, error.into())
285     }
286
287     fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
288         Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
289     }
290
291     /// Creates a new I/O error from a known kind of error as well as a
292     /// constant message.
293     ///
294     /// This function does not allocate.
295     ///
296     /// This function should maybe change to
297     /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
298     /// in the future, when const generics allow that.
299     #[inline]
300     pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
301         Self { repr: Repr::SimpleMessage(kind, message) }
302     }
303
304     /// Returns an error representing the last OS error which occurred.
305     ///
306     /// This function reads the value of `errno` for the target platform (e.g.
307     /// `GetLastError` on Windows) and will return a corresponding instance of
308     /// [`Error`] for the error code.
309     ///
310     /// # Examples
311     ///
312     /// ```
313     /// use std::io::Error;
314     ///
315     /// println!("last OS error: {:?}", Error::last_os_error());
316     /// ```
317     #[stable(feature = "rust1", since = "1.0.0")]
318     #[inline]
319     pub fn last_os_error() -> Error {
320         Error::from_raw_os_error(sys::os::errno() as i32)
321     }
322
323     /// Creates a new instance of an [`Error`] from a particular OS error code.
324     ///
325     /// # Examples
326     ///
327     /// On Linux:
328     ///
329     /// ```
330     /// # if cfg!(target_os = "linux") {
331     /// use std::io;
332     ///
333     /// let error = io::Error::from_raw_os_error(22);
334     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
335     /// # }
336     /// ```
337     ///
338     /// On Windows:
339     ///
340     /// ```
341     /// # if cfg!(windows) {
342     /// use std::io;
343     ///
344     /// let error = io::Error::from_raw_os_error(10022);
345     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
346     /// # }
347     /// ```
348     #[stable(feature = "rust1", since = "1.0.0")]
349     #[inline]
350     pub fn from_raw_os_error(code: i32) -> Error {
351         Error { repr: Repr::Os(code) }
352     }
353
354     /// Returns the OS error that this error represents (if any).
355     ///
356     /// If this [`Error`] was constructed via [`last_os_error`] or
357     /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
358     /// it will return [`None`].
359     ///
360     /// [`last_os_error`]: Error::last_os_error
361     /// [`from_raw_os_error`]: Error::from_raw_os_error
362     ///
363     /// # Examples
364     ///
365     /// ```
366     /// use std::io::{Error, ErrorKind};
367     ///
368     /// fn print_os_error(err: &Error) {
369     ///     if let Some(raw_os_err) = err.raw_os_error() {
370     ///         println!("raw OS error: {:?}", raw_os_err);
371     ///     } else {
372     ///         println!("Not an OS error");
373     ///     }
374     /// }
375     ///
376     /// fn main() {
377     ///     // Will print "raw OS error: ...".
378     ///     print_os_error(&Error::last_os_error());
379     ///     // Will print "Not an OS error".
380     ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
381     /// }
382     /// ```
383     #[stable(feature = "rust1", since = "1.0.0")]
384     #[inline]
385     pub fn raw_os_error(&self) -> Option<i32> {
386         match self.repr {
387             Repr::Os(i) => Some(i),
388             Repr::Custom(..) => None,
389             Repr::Simple(..) => None,
390             Repr::SimpleMessage(..) => None,
391         }
392     }
393
394     /// Returns a reference to the inner error wrapped by this error (if any).
395     ///
396     /// If this [`Error`] was constructed via [`new`] then this function will
397     /// return [`Some`], otherwise it will return [`None`].
398     ///
399     /// [`new`]: Error::new
400     ///
401     /// # Examples
402     ///
403     /// ```
404     /// use std::io::{Error, ErrorKind};
405     ///
406     /// fn print_error(err: &Error) {
407     ///     if let Some(inner_err) = err.get_ref() {
408     ///         println!("Inner error: {:?}", inner_err);
409     ///     } else {
410     ///         println!("No inner error");
411     ///     }
412     /// }
413     ///
414     /// fn main() {
415     ///     // Will print "No inner error".
416     ///     print_error(&Error::last_os_error());
417     ///     // Will print "Inner error: ...".
418     ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
419     /// }
420     /// ```
421     #[stable(feature = "io_error_inner", since = "1.3.0")]
422     #[inline]
423     pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
424         match self.repr {
425             Repr::Os(..) => None,
426             Repr::Simple(..) => None,
427             Repr::SimpleMessage(..) => None,
428             Repr::Custom(ref c) => Some(&*c.error),
429         }
430     }
431
432     /// Returns a mutable reference to the inner error wrapped by this error
433     /// (if any).
434     ///
435     /// If this [`Error`] was constructed via [`new`] then this function will
436     /// return [`Some`], otherwise it will return [`None`].
437     ///
438     /// [`new`]: Error::new
439     ///
440     /// # Examples
441     ///
442     /// ```
443     /// use std::io::{Error, ErrorKind};
444     /// use std::{error, fmt};
445     /// use std::fmt::Display;
446     ///
447     /// #[derive(Debug)]
448     /// struct MyError {
449     ///     v: String,
450     /// }
451     ///
452     /// impl MyError {
453     ///     fn new() -> MyError {
454     ///         MyError {
455     ///             v: "oh no!".to_string()
456     ///         }
457     ///     }
458     ///
459     ///     fn change_message(&mut self, new_message: &str) {
460     ///         self.v = new_message.to_string();
461     ///     }
462     /// }
463     ///
464     /// impl error::Error for MyError {}
465     ///
466     /// impl Display for MyError {
467     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
468     ///         write!(f, "MyError: {}", &self.v)
469     ///     }
470     /// }
471     ///
472     /// fn change_error(mut err: Error) -> Error {
473     ///     if let Some(inner_err) = err.get_mut() {
474     ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
475     ///     }
476     ///     err
477     /// }
478     ///
479     /// fn print_error(err: &Error) {
480     ///     if let Some(inner_err) = err.get_ref() {
481     ///         println!("Inner error: {}", inner_err);
482     ///     } else {
483     ///         println!("No inner error");
484     ///     }
485     /// }
486     ///
487     /// fn main() {
488     ///     // Will print "No inner error".
489     ///     print_error(&change_error(Error::last_os_error()));
490     ///     // Will print "Inner error: ...".
491     ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
492     /// }
493     /// ```
494     #[stable(feature = "io_error_inner", since = "1.3.0")]
495     #[inline]
496     pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
497         match self.repr {
498             Repr::Os(..) => None,
499             Repr::Simple(..) => None,
500             Repr::SimpleMessage(..) => None,
501             Repr::Custom(ref mut c) => Some(&mut *c.error),
502         }
503     }
504
505     /// Consumes the `Error`, returning its inner error (if any).
506     ///
507     /// If this [`Error`] was constructed via [`new`] then this function will
508     /// return [`Some`], otherwise it will return [`None`].
509     ///
510     /// [`new`]: Error::new
511     ///
512     /// # Examples
513     ///
514     /// ```
515     /// use std::io::{Error, ErrorKind};
516     ///
517     /// fn print_error(err: Error) {
518     ///     if let Some(inner_err) = err.into_inner() {
519     ///         println!("Inner error: {}", inner_err);
520     ///     } else {
521     ///         println!("No inner error");
522     ///     }
523     /// }
524     ///
525     /// fn main() {
526     ///     // Will print "No inner error".
527     ///     print_error(Error::last_os_error());
528     ///     // Will print "Inner error: ...".
529     ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
530     /// }
531     /// ```
532     #[stable(feature = "io_error_inner", since = "1.3.0")]
533     #[inline]
534     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
535         match self.repr {
536             Repr::Os(..) => None,
537             Repr::Simple(..) => None,
538             Repr::SimpleMessage(..) => None,
539             Repr::Custom(c) => Some(c.error),
540         }
541     }
542
543     /// Returns the corresponding [`ErrorKind`] for this error.
544     ///
545     /// # Examples
546     ///
547     /// ```
548     /// use std::io::{Error, ErrorKind};
549     ///
550     /// fn print_error(err: Error) {
551     ///     println!("{:?}", err.kind());
552     /// }
553     ///
554     /// fn main() {
555     ///     // Will print "Uncategorized".
556     ///     print_error(Error::last_os_error());
557     ///     // Will print "AddrInUse".
558     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
559     /// }
560     /// ```
561     #[stable(feature = "rust1", since = "1.0.0")]
562     #[inline]
563     pub fn kind(&self) -> ErrorKind {
564         match self.repr {
565             Repr::Os(code) => sys::decode_error_kind(code),
566             Repr::Custom(ref c) => c.kind,
567             Repr::Simple(kind) => kind,
568             Repr::SimpleMessage(kind, _) => kind,
569         }
570     }
571 }
572
573 impl fmt::Debug for Repr {
574     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
575         match *self {
576             Repr::Os(code) => fmt
577                 .debug_struct("Os")
578                 .field("code", &code)
579                 .field("kind", &sys::decode_error_kind(code))
580                 .field("message", &sys::os::error_string(code))
581                 .finish(),
582             Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
583             Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
584             Repr::SimpleMessage(kind, &message) => {
585                 fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
586             }
587         }
588     }
589 }
590
591 #[stable(feature = "rust1", since = "1.0.0")]
592 impl fmt::Display for Error {
593     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
594         match self.repr {
595             Repr::Os(code) => {
596                 let detail = sys::os::error_string(code);
597                 write!(fmt, "{} (os error {})", detail, code)
598             }
599             Repr::Custom(ref c) => c.error.fmt(fmt),
600             Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
601             Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
602         }
603     }
604 }
605
606 #[stable(feature = "rust1", since = "1.0.0")]
607 impl error::Error for Error {
608     #[allow(deprecated, deprecated_in_future)]
609     fn description(&self) -> &str {
610         match self.repr {
611             Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
612             Repr::SimpleMessage(_, &msg) => msg,
613             Repr::Custom(ref c) => c.error.description(),
614         }
615     }
616
617     #[allow(deprecated)]
618     fn cause(&self) -> Option<&dyn error::Error> {
619         match self.repr {
620             Repr::Os(..) => None,
621             Repr::Simple(..) => None,
622             Repr::SimpleMessage(..) => None,
623             Repr::Custom(ref c) => c.error.cause(),
624         }
625     }
626
627     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
628         match self.repr {
629             Repr::Os(..) => None,
630             Repr::Simple(..) => None,
631             Repr::SimpleMessage(..) => None,
632             Repr::Custom(ref c) => c.error.source(),
633         }
634     }
635 }
636
637 fn _assert_error_is_sync_send() {
638     fn _is_sync_send<T: Sync + Send>() {}
639     _is_sync_send::<Error>();
640 }