]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/error.rs
Rollup merge of #84815 - richkadel:coverage-docs-update-2021-05, r=tmandry
[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     /// Any I/O error not part of this list.
167     ///
168     /// Errors that are `Other` now may move to a different or a new
169     /// [`ErrorKind`] variant in the future. It is not recommended to match
170     /// an error against `Other` and to expect any additional characteristics,
171     /// e.g., a specific [`Error::raw_os_error`] return value.
172     #[stable(feature = "rust1", since = "1.0.0")]
173     Other,
174
175     /// An error returned when an operation could not be completed because an
176     /// "end of file" was reached prematurely.
177     ///
178     /// This typically means that an operation could only succeed if it read a
179     /// particular number of bytes but only a smaller number of bytes could be
180     /// read.
181     #[stable(feature = "read_exact", since = "1.6.0")]
182     UnexpectedEof,
183
184     /// This operation is unsupported on this platform.
185     ///
186     /// This means that the operation can never succeed.
187     #[stable(feature = "unsupported_error", since = "1.53.0")]
188     Unsupported,
189
190     /// An operation could not be completed, because it failed
191     /// to allocate enough memory.
192     #[stable(feature = "out_of_memory_error", since = "1.54.0")]
193     OutOfMemory,
194 }
195
196 impl ErrorKind {
197     pub(crate) fn as_str(&self) -> &'static str {
198         match *self {
199             ErrorKind::NotFound => "entity not found",
200             ErrorKind::PermissionDenied => "permission denied",
201             ErrorKind::ConnectionRefused => "connection refused",
202             ErrorKind::ConnectionReset => "connection reset",
203             ErrorKind::ConnectionAborted => "connection aborted",
204             ErrorKind::NotConnected => "not connected",
205             ErrorKind::AddrInUse => "address in use",
206             ErrorKind::AddrNotAvailable => "address not available",
207             ErrorKind::BrokenPipe => "broken pipe",
208             ErrorKind::AlreadyExists => "entity already exists",
209             ErrorKind::WouldBlock => "operation would block",
210             ErrorKind::InvalidInput => "invalid input parameter",
211             ErrorKind::InvalidData => "invalid data",
212             ErrorKind::TimedOut => "timed out",
213             ErrorKind::WriteZero => "write zero",
214             ErrorKind::Interrupted => "operation interrupted",
215             ErrorKind::Other => "other os error",
216             ErrorKind::UnexpectedEof => "unexpected end of file",
217             ErrorKind::Unsupported => "unsupported",
218             ErrorKind::OutOfMemory => "out of memory",
219         }
220     }
221 }
222
223 /// Intended for use for errors not exposed to the user, where allocating onto
224 /// the heap (for normal construction via Error::new) is too costly.
225 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
226 impl From<ErrorKind> for Error {
227     /// Converts an [`ErrorKind`] into an [`Error`].
228     ///
229     /// This conversion allocates a new error with a simple representation of error kind.
230     ///
231     /// # Examples
232     ///
233     /// ```
234     /// use std::io::{Error, ErrorKind};
235     ///
236     /// let not_found = ErrorKind::NotFound;
237     /// let error = Error::from(not_found);
238     /// assert_eq!("entity not found", format!("{}", error));
239     /// ```
240     #[inline]
241     fn from(kind: ErrorKind) -> Error {
242         Error { repr: Repr::Simple(kind) }
243     }
244 }
245
246 impl Error {
247     /// Creates a new I/O error from a known kind of error as well as an
248     /// arbitrary error payload.
249     ///
250     /// This function is used to generically create I/O errors which do not
251     /// originate from the OS itself. The `error` argument is an arbitrary
252     /// payload which will be contained in this [`Error`].
253     ///
254     /// # Examples
255     ///
256     /// ```
257     /// use std::io::{Error, ErrorKind};
258     ///
259     /// // errors can be created from strings
260     /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
261     ///
262     /// // errors can also be created from other errors
263     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
264     /// ```
265     #[stable(feature = "rust1", since = "1.0.0")]
266     pub fn new<E>(kind: ErrorKind, error: E) -> Error
267     where
268         E: Into<Box<dyn error::Error + Send + Sync>>,
269     {
270         Self::_new(kind, error.into())
271     }
272
273     fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
274         Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
275     }
276
277     /// Creates a new I/O error from a known kind of error as well as a
278     /// constant message.
279     ///
280     /// This function does not allocate.
281     ///
282     /// This function should maybe change to
283     /// `new_const<const MSG: &'static str>(kind: ErrorKind)`
284     /// in the future, when const generics allow that.
285     #[inline]
286     pub(crate) const fn new_const(kind: ErrorKind, message: &'static &'static str) -> Error {
287         Self { repr: Repr::SimpleMessage(kind, message) }
288     }
289
290     /// Returns an error representing the last OS error which occurred.
291     ///
292     /// This function reads the value of `errno` for the target platform (e.g.
293     /// `GetLastError` on Windows) and will return a corresponding instance of
294     /// [`Error`] for the error code.
295     ///
296     /// # Examples
297     ///
298     /// ```
299     /// use std::io::Error;
300     ///
301     /// println!("last OS error: {:?}", Error::last_os_error());
302     /// ```
303     #[stable(feature = "rust1", since = "1.0.0")]
304     #[inline]
305     pub fn last_os_error() -> Error {
306         Error::from_raw_os_error(sys::os::errno() as i32)
307     }
308
309     /// Creates a new instance of an [`Error`] from a particular OS error code.
310     ///
311     /// # Examples
312     ///
313     /// On Linux:
314     ///
315     /// ```
316     /// # if cfg!(target_os = "linux") {
317     /// use std::io;
318     ///
319     /// let error = io::Error::from_raw_os_error(22);
320     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
321     /// # }
322     /// ```
323     ///
324     /// On Windows:
325     ///
326     /// ```
327     /// # if cfg!(windows) {
328     /// use std::io;
329     ///
330     /// let error = io::Error::from_raw_os_error(10022);
331     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
332     /// # }
333     /// ```
334     #[stable(feature = "rust1", since = "1.0.0")]
335     #[inline]
336     pub fn from_raw_os_error(code: i32) -> Error {
337         Error { repr: Repr::Os(code) }
338     }
339
340     /// Returns the OS error that this error represents (if any).
341     ///
342     /// If this [`Error`] was constructed via [`last_os_error`] or
343     /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
344     /// it will return [`None`].
345     ///
346     /// [`last_os_error`]: Error::last_os_error
347     /// [`from_raw_os_error`]: Error::from_raw_os_error
348     ///
349     /// # Examples
350     ///
351     /// ```
352     /// use std::io::{Error, ErrorKind};
353     ///
354     /// fn print_os_error(err: &Error) {
355     ///     if let Some(raw_os_err) = err.raw_os_error() {
356     ///         println!("raw OS error: {:?}", raw_os_err);
357     ///     } else {
358     ///         println!("Not an OS error");
359     ///     }
360     /// }
361     ///
362     /// fn main() {
363     ///     // Will print "raw OS error: ...".
364     ///     print_os_error(&Error::last_os_error());
365     ///     // Will print "Not an OS error".
366     ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
367     /// }
368     /// ```
369     #[stable(feature = "rust1", since = "1.0.0")]
370     #[inline]
371     pub fn raw_os_error(&self) -> Option<i32> {
372         match self.repr {
373             Repr::Os(i) => Some(i),
374             Repr::Custom(..) => None,
375             Repr::Simple(..) => None,
376             Repr::SimpleMessage(..) => None,
377         }
378     }
379
380     /// Returns a reference to the inner error wrapped by this error (if any).
381     ///
382     /// If this [`Error`] was constructed via [`new`] then this function will
383     /// return [`Some`], otherwise it will return [`None`].
384     ///
385     /// [`new`]: Error::new
386     ///
387     /// # Examples
388     ///
389     /// ```
390     /// use std::io::{Error, ErrorKind};
391     ///
392     /// fn print_error(err: &Error) {
393     ///     if let Some(inner_err) = err.get_ref() {
394     ///         println!("Inner error: {:?}", inner_err);
395     ///     } else {
396     ///         println!("No inner error");
397     ///     }
398     /// }
399     ///
400     /// fn main() {
401     ///     // Will print "No inner error".
402     ///     print_error(&Error::last_os_error());
403     ///     // Will print "Inner error: ...".
404     ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
405     /// }
406     /// ```
407     #[stable(feature = "io_error_inner", since = "1.3.0")]
408     #[inline]
409     pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
410         match self.repr {
411             Repr::Os(..) => None,
412             Repr::Simple(..) => None,
413             Repr::SimpleMessage(..) => None,
414             Repr::Custom(ref c) => Some(&*c.error),
415         }
416     }
417
418     /// Returns a mutable reference to the inner error wrapped by this error
419     /// (if any).
420     ///
421     /// If this [`Error`] was constructed via [`new`] then this function will
422     /// return [`Some`], otherwise it will return [`None`].
423     ///
424     /// [`new`]: Error::new
425     ///
426     /// # Examples
427     ///
428     /// ```
429     /// use std::io::{Error, ErrorKind};
430     /// use std::{error, fmt};
431     /// use std::fmt::Display;
432     ///
433     /// #[derive(Debug)]
434     /// struct MyError {
435     ///     v: String,
436     /// }
437     ///
438     /// impl MyError {
439     ///     fn new() -> MyError {
440     ///         MyError {
441     ///             v: "oh no!".to_string()
442     ///         }
443     ///     }
444     ///
445     ///     fn change_message(&mut self, new_message: &str) {
446     ///         self.v = new_message.to_string();
447     ///     }
448     /// }
449     ///
450     /// impl error::Error for MyError {}
451     ///
452     /// impl Display for MyError {
453     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454     ///         write!(f, "MyError: {}", &self.v)
455     ///     }
456     /// }
457     ///
458     /// fn change_error(mut err: Error) -> Error {
459     ///     if let Some(inner_err) = err.get_mut() {
460     ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
461     ///     }
462     ///     err
463     /// }
464     ///
465     /// fn print_error(err: &Error) {
466     ///     if let Some(inner_err) = err.get_ref() {
467     ///         println!("Inner error: {}", inner_err);
468     ///     } else {
469     ///         println!("No inner error");
470     ///     }
471     /// }
472     ///
473     /// fn main() {
474     ///     // Will print "No inner error".
475     ///     print_error(&change_error(Error::last_os_error()));
476     ///     // Will print "Inner error: ...".
477     ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
478     /// }
479     /// ```
480     #[stable(feature = "io_error_inner", since = "1.3.0")]
481     #[inline]
482     pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
483         match self.repr {
484             Repr::Os(..) => None,
485             Repr::Simple(..) => None,
486             Repr::SimpleMessage(..) => None,
487             Repr::Custom(ref mut c) => Some(&mut *c.error),
488         }
489     }
490
491     /// Consumes the `Error`, returning its inner error (if any).
492     ///
493     /// If this [`Error`] was constructed via [`new`] then this function will
494     /// return [`Some`], otherwise it will return [`None`].
495     ///
496     /// [`new`]: Error::new
497     ///
498     /// # Examples
499     ///
500     /// ```
501     /// use std::io::{Error, ErrorKind};
502     ///
503     /// fn print_error(err: Error) {
504     ///     if let Some(inner_err) = err.into_inner() {
505     ///         println!("Inner error: {}", inner_err);
506     ///     } else {
507     ///         println!("No inner error");
508     ///     }
509     /// }
510     ///
511     /// fn main() {
512     ///     // Will print "No inner error".
513     ///     print_error(Error::last_os_error());
514     ///     // Will print "Inner error: ...".
515     ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
516     /// }
517     /// ```
518     #[stable(feature = "io_error_inner", since = "1.3.0")]
519     #[inline]
520     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
521         match self.repr {
522             Repr::Os(..) => None,
523             Repr::Simple(..) => None,
524             Repr::SimpleMessage(..) => None,
525             Repr::Custom(c) => Some(c.error),
526         }
527     }
528
529     /// Returns the corresponding [`ErrorKind`] for this error.
530     ///
531     /// # Examples
532     ///
533     /// ```
534     /// use std::io::{Error, ErrorKind};
535     ///
536     /// fn print_error(err: Error) {
537     ///     println!("{:?}", err.kind());
538     /// }
539     ///
540     /// fn main() {
541     ///     // Will print "Other".
542     ///     print_error(Error::last_os_error());
543     ///     // Will print "AddrInUse".
544     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
545     /// }
546     /// ```
547     #[stable(feature = "rust1", since = "1.0.0")]
548     #[inline]
549     pub fn kind(&self) -> ErrorKind {
550         match self.repr {
551             Repr::Os(code) => sys::decode_error_kind(code),
552             Repr::Custom(ref c) => c.kind,
553             Repr::Simple(kind) => kind,
554             Repr::SimpleMessage(kind, _) => kind,
555         }
556     }
557 }
558
559 impl fmt::Debug for Repr {
560     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
561         match *self {
562             Repr::Os(code) => fmt
563                 .debug_struct("Os")
564                 .field("code", &code)
565                 .field("kind", &sys::decode_error_kind(code))
566                 .field("message", &sys::os::error_string(code))
567                 .finish(),
568             Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
569             Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
570             Repr::SimpleMessage(kind, &message) => {
571                 fmt.debug_struct("Error").field("kind", &kind).field("message", &message).finish()
572             }
573         }
574     }
575 }
576
577 #[stable(feature = "rust1", since = "1.0.0")]
578 impl fmt::Display for Error {
579     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
580         match self.repr {
581             Repr::Os(code) => {
582                 let detail = sys::os::error_string(code);
583                 write!(fmt, "{} (os error {})", detail, code)
584             }
585             Repr::Custom(ref c) => c.error.fmt(fmt),
586             Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
587             Repr::SimpleMessage(_, &msg) => msg.fmt(fmt),
588         }
589     }
590 }
591
592 #[stable(feature = "rust1", since = "1.0.0")]
593 impl error::Error for Error {
594     #[allow(deprecated, deprecated_in_future)]
595     fn description(&self) -> &str {
596         match self.repr {
597             Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
598             Repr::SimpleMessage(_, &msg) => msg,
599             Repr::Custom(ref c) => c.error.description(),
600         }
601     }
602
603     #[allow(deprecated)]
604     fn cause(&self) -> Option<&dyn error::Error> {
605         match self.repr {
606             Repr::Os(..) => None,
607             Repr::Simple(..) => None,
608             Repr::SimpleMessage(..) => None,
609             Repr::Custom(ref c) => c.error.cause(),
610         }
611     }
612
613     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
614         match self.repr {
615             Repr::Os(..) => None,
616             Repr::Simple(..) => None,
617             Repr::SimpleMessage(..) => None,
618             Repr::Custom(ref c) => c.error.source(),
619         }
620     }
621 }
622
623 fn _assert_error_is_sync_send() {
624     fn _is_sync_send<T: Sync + Send>() {}
625     _is_sync_send::<Error>();
626 }