]> git.lizzy.rs Git - rust.git/blob - library/std/src/io/error.rs
Add a `std::io::read_to_string` function
[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     Custom(Box<Custom>),
73 }
74
75 #[derive(Debug)]
76 struct Custom {
77     kind: ErrorKind,
78     error: Box<dyn error::Error + Send + Sync>,
79 }
80
81 /// A list specifying general categories of I/O error.
82 ///
83 /// This list is intended to grow over time and it is not recommended to
84 /// exhaustively match against it.
85 ///
86 /// It is used with the [`io::Error`] type.
87 ///
88 /// [`io::Error`]: Error
89 #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
90 #[stable(feature = "rust1", since = "1.0.0")]
91 #[allow(deprecated)]
92 #[non_exhaustive]
93 pub enum ErrorKind {
94     /// An entity was not found, often a file.
95     #[stable(feature = "rust1", since = "1.0.0")]
96     NotFound,
97     /// The operation lacked the necessary privileges to complete.
98     #[stable(feature = "rust1", since = "1.0.0")]
99     PermissionDenied,
100     /// The connection was refused by the remote server.
101     #[stable(feature = "rust1", since = "1.0.0")]
102     ConnectionRefused,
103     /// The connection was reset by the remote server.
104     #[stable(feature = "rust1", since = "1.0.0")]
105     ConnectionReset,
106     /// The connection was aborted (terminated) by the remote server.
107     #[stable(feature = "rust1", since = "1.0.0")]
108     ConnectionAborted,
109     /// The network operation failed because it was not connected yet.
110     #[stable(feature = "rust1", since = "1.0.0")]
111     NotConnected,
112     /// A socket address could not be bound because the address is already in
113     /// use elsewhere.
114     #[stable(feature = "rust1", since = "1.0.0")]
115     AddrInUse,
116     /// A nonexistent interface was requested or the requested address was not
117     /// local.
118     #[stable(feature = "rust1", since = "1.0.0")]
119     AddrNotAvailable,
120     /// The operation failed because a pipe was closed.
121     #[stable(feature = "rust1", since = "1.0.0")]
122     BrokenPipe,
123     /// An entity already exists, often a file.
124     #[stable(feature = "rust1", since = "1.0.0")]
125     AlreadyExists,
126     /// The operation needs to block to complete, but the blocking operation was
127     /// requested to not occur.
128     #[stable(feature = "rust1", since = "1.0.0")]
129     WouldBlock,
130     /// A parameter was incorrect.
131     #[stable(feature = "rust1", since = "1.0.0")]
132     InvalidInput,
133     /// Data not valid for the operation were encountered.
134     ///
135     /// Unlike [`InvalidInput`], this typically means that the operation
136     /// parameters were valid, however the error was caused by malformed
137     /// input data.
138     ///
139     /// For example, a function that reads a file into a string will error with
140     /// `InvalidData` if the file's contents are not valid UTF-8.
141     ///
142     /// [`InvalidInput`]: ErrorKind::InvalidInput
143     #[stable(feature = "io_invalid_data", since = "1.2.0")]
144     InvalidData,
145     /// The I/O operation's timeout expired, causing it to be canceled.
146     #[stable(feature = "rust1", since = "1.0.0")]
147     TimedOut,
148     /// An error returned when an operation could not be completed because a
149     /// call to [`write`] returned [`Ok(0)`].
150     ///
151     /// This typically means that an operation could only succeed if it wrote a
152     /// particular number of bytes but only a smaller number of bytes could be
153     /// written.
154     ///
155     /// [`write`]: crate::io::Write::write
156     /// [`Ok(0)`]: Ok
157     #[stable(feature = "rust1", since = "1.0.0")]
158     WriteZero,
159     /// This operation was interrupted.
160     ///
161     /// Interrupted operations can typically be retried.
162     #[stable(feature = "rust1", since = "1.0.0")]
163     Interrupted,
164     /// Any I/O error not part of this list.
165     ///
166     /// Errors that are `Other` now may move to a different or a new
167     /// [`ErrorKind`] variant in the future. It is not recommended to match
168     /// an error against `Other` and to expect any additional characteristics,
169     /// e.g., a specific [`Error::raw_os_error`] return value.
170     #[stable(feature = "rust1", since = "1.0.0")]
171     Other,
172
173     /// An error returned when an operation could not be completed because an
174     /// "end of file" was reached prematurely.
175     ///
176     /// This typically means that an operation could only succeed if it read a
177     /// particular number of bytes but only a smaller number of bytes could be
178     /// read.
179     #[stable(feature = "read_exact", since = "1.6.0")]
180     UnexpectedEof,
181 }
182
183 impl ErrorKind {
184     pub(crate) fn as_str(&self) -> &'static str {
185         match *self {
186             ErrorKind::NotFound => "entity not found",
187             ErrorKind::PermissionDenied => "permission denied",
188             ErrorKind::ConnectionRefused => "connection refused",
189             ErrorKind::ConnectionReset => "connection reset",
190             ErrorKind::ConnectionAborted => "connection aborted",
191             ErrorKind::NotConnected => "not connected",
192             ErrorKind::AddrInUse => "address in use",
193             ErrorKind::AddrNotAvailable => "address not available",
194             ErrorKind::BrokenPipe => "broken pipe",
195             ErrorKind::AlreadyExists => "entity already exists",
196             ErrorKind::WouldBlock => "operation would block",
197             ErrorKind::InvalidInput => "invalid input parameter",
198             ErrorKind::InvalidData => "invalid data",
199             ErrorKind::TimedOut => "timed out",
200             ErrorKind::WriteZero => "write zero",
201             ErrorKind::Interrupted => "operation interrupted",
202             ErrorKind::Other => "other os error",
203             ErrorKind::UnexpectedEof => "unexpected end of file",
204         }
205     }
206 }
207
208 /// Intended for use for errors not exposed to the user, where allocating onto
209 /// the heap (for normal construction via Error::new) is too costly.
210 #[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
211 impl From<ErrorKind> for Error {
212     /// Converts an [`ErrorKind`] into an [`Error`].
213     ///
214     /// This conversion allocates a new error with a simple representation of error kind.
215     ///
216     /// # Examples
217     ///
218     /// ```
219     /// use std::io::{Error, ErrorKind};
220     ///
221     /// let not_found = ErrorKind::NotFound;
222     /// let error = Error::from(not_found);
223     /// assert_eq!("entity not found", format!("{}", error));
224     /// ```
225     #[inline]
226     fn from(kind: ErrorKind) -> Error {
227         Error { repr: Repr::Simple(kind) }
228     }
229 }
230
231 impl Error {
232     /// Creates a new I/O error from a known kind of error as well as an
233     /// arbitrary error payload.
234     ///
235     /// This function is used to generically create I/O errors which do not
236     /// originate from the OS itself. The `error` argument is an arbitrary
237     /// payload which will be contained in this [`Error`].
238     ///
239     /// # Examples
240     ///
241     /// ```
242     /// use std::io::{Error, ErrorKind};
243     ///
244     /// // errors can be created from strings
245     /// let custom_error = Error::new(ErrorKind::Other, "oh no!");
246     ///
247     /// // errors can also be created from other errors
248     /// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
249     /// ```
250     #[stable(feature = "rust1", since = "1.0.0")]
251     pub fn new<E>(kind: ErrorKind, error: E) -> Error
252     where
253         E: Into<Box<dyn error::Error + Send + Sync>>,
254     {
255         Self::_new(kind, error.into())
256     }
257
258     fn _new(kind: ErrorKind, error: Box<dyn error::Error + Send + Sync>) -> Error {
259         Error { repr: Repr::Custom(Box::new(Custom { kind, error })) }
260     }
261
262     /// Returns an error representing the last OS error which occurred.
263     ///
264     /// This function reads the value of `errno` for the target platform (e.g.
265     /// `GetLastError` on Windows) and will return a corresponding instance of
266     /// [`Error`] for the error code.
267     ///
268     /// # Examples
269     ///
270     /// ```
271     /// use std::io::Error;
272     ///
273     /// println!("last OS error: {:?}", Error::last_os_error());
274     /// ```
275     #[stable(feature = "rust1", since = "1.0.0")]
276     pub fn last_os_error() -> Error {
277         Error::from_raw_os_error(sys::os::errno() as i32)
278     }
279
280     /// Creates a new instance of an [`Error`] from a particular OS error code.
281     ///
282     /// # Examples
283     ///
284     /// On Linux:
285     ///
286     /// ```
287     /// # if cfg!(target_os = "linux") {
288     /// use std::io;
289     ///
290     /// let error = io::Error::from_raw_os_error(22);
291     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
292     /// # }
293     /// ```
294     ///
295     /// On Windows:
296     ///
297     /// ```
298     /// # if cfg!(windows) {
299     /// use std::io;
300     ///
301     /// let error = io::Error::from_raw_os_error(10022);
302     /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
303     /// # }
304     /// ```
305     #[stable(feature = "rust1", since = "1.0.0")]
306     pub fn from_raw_os_error(code: i32) -> Error {
307         Error { repr: Repr::Os(code) }
308     }
309
310     /// Returns the OS error that this error represents (if any).
311     ///
312     /// If this [`Error`] was constructed via [`last_os_error`] or
313     /// [`from_raw_os_error`], then this function will return [`Some`], otherwise
314     /// it will return [`None`].
315     ///
316     /// [`last_os_error`]: Error::last_os_error
317     /// [`from_raw_os_error`]: Error::from_raw_os_error
318     ///
319     /// # Examples
320     ///
321     /// ```
322     /// use std::io::{Error, ErrorKind};
323     ///
324     /// fn print_os_error(err: &Error) {
325     ///     if let Some(raw_os_err) = err.raw_os_error() {
326     ///         println!("raw OS error: {:?}", raw_os_err);
327     ///     } else {
328     ///         println!("Not an OS error");
329     ///     }
330     /// }
331     ///
332     /// fn main() {
333     ///     // Will print "raw OS error: ...".
334     ///     print_os_error(&Error::last_os_error());
335     ///     // Will print "Not an OS error".
336     ///     print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
337     /// }
338     /// ```
339     #[stable(feature = "rust1", since = "1.0.0")]
340     pub fn raw_os_error(&self) -> Option<i32> {
341         match self.repr {
342             Repr::Os(i) => Some(i),
343             Repr::Custom(..) => None,
344             Repr::Simple(..) => None,
345         }
346     }
347
348     /// Returns a reference to the inner error wrapped by this error (if any).
349     ///
350     /// If this [`Error`] was constructed via [`new`] then this function will
351     /// return [`Some`], otherwise it will return [`None`].
352     ///
353     /// [`new`]: Error::new
354     ///
355     /// # Examples
356     ///
357     /// ```
358     /// use std::io::{Error, ErrorKind};
359     ///
360     /// fn print_error(err: &Error) {
361     ///     if let Some(inner_err) = err.get_ref() {
362     ///         println!("Inner error: {:?}", inner_err);
363     ///     } else {
364     ///         println!("No inner error");
365     ///     }
366     /// }
367     ///
368     /// fn main() {
369     ///     // Will print "No inner error".
370     ///     print_error(&Error::last_os_error());
371     ///     // Will print "Inner error: ...".
372     ///     print_error(&Error::new(ErrorKind::Other, "oh no!"));
373     /// }
374     /// ```
375     #[stable(feature = "io_error_inner", since = "1.3.0")]
376     pub fn get_ref(&self) -> Option<&(dyn error::Error + Send + Sync + 'static)> {
377         match self.repr {
378             Repr::Os(..) => None,
379             Repr::Simple(..) => None,
380             Repr::Custom(ref c) => Some(&*c.error),
381         }
382     }
383
384     /// Returns a mutable reference to the inner error wrapped by this error
385     /// (if any).
386     ///
387     /// If this [`Error`] was constructed via [`new`] then this function will
388     /// return [`Some`], otherwise it will return [`None`].
389     ///
390     /// [`new`]: Error::new
391     ///
392     /// # Examples
393     ///
394     /// ```
395     /// use std::io::{Error, ErrorKind};
396     /// use std::{error, fmt};
397     /// use std::fmt::Display;
398     ///
399     /// #[derive(Debug)]
400     /// struct MyError {
401     ///     v: String,
402     /// }
403     ///
404     /// impl MyError {
405     ///     fn new() -> MyError {
406     ///         MyError {
407     ///             v: "oh no!".to_string()
408     ///         }
409     ///     }
410     ///
411     ///     fn change_message(&mut self, new_message: &str) {
412     ///         self.v = new_message.to_string();
413     ///     }
414     /// }
415     ///
416     /// impl error::Error for MyError {}
417     ///
418     /// impl Display for MyError {
419     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
420     ///         write!(f, "MyError: {}", &self.v)
421     ///     }
422     /// }
423     ///
424     /// fn change_error(mut err: Error) -> Error {
425     ///     if let Some(inner_err) = err.get_mut() {
426     ///         inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
427     ///     }
428     ///     err
429     /// }
430     ///
431     /// fn print_error(err: &Error) {
432     ///     if let Some(inner_err) = err.get_ref() {
433     ///         println!("Inner error: {}", inner_err);
434     ///     } else {
435     ///         println!("No inner error");
436     ///     }
437     /// }
438     ///
439     /// fn main() {
440     ///     // Will print "No inner error".
441     ///     print_error(&change_error(Error::last_os_error()));
442     ///     // Will print "Inner error: ...".
443     ///     print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
444     /// }
445     /// ```
446     #[stable(feature = "io_error_inner", since = "1.3.0")]
447     pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error + Send + Sync + 'static)> {
448         match self.repr {
449             Repr::Os(..) => None,
450             Repr::Simple(..) => None,
451             Repr::Custom(ref mut c) => Some(&mut *c.error),
452         }
453     }
454
455     /// Consumes the `Error`, returning its inner error (if any).
456     ///
457     /// If this [`Error`] was constructed via [`new`] then this function will
458     /// return [`Some`], otherwise it will return [`None`].
459     ///
460     /// [`new`]: Error::new
461     ///
462     /// # Examples
463     ///
464     /// ```
465     /// use std::io::{Error, ErrorKind};
466     ///
467     /// fn print_error(err: Error) {
468     ///     if let Some(inner_err) = err.into_inner() {
469     ///         println!("Inner error: {}", inner_err);
470     ///     } else {
471     ///         println!("No inner error");
472     ///     }
473     /// }
474     ///
475     /// fn main() {
476     ///     // Will print "No inner error".
477     ///     print_error(Error::last_os_error());
478     ///     // Will print "Inner error: ...".
479     ///     print_error(Error::new(ErrorKind::Other, "oh no!"));
480     /// }
481     /// ```
482     #[stable(feature = "io_error_inner", since = "1.3.0")]
483     pub fn into_inner(self) -> Option<Box<dyn error::Error + Send + Sync>> {
484         match self.repr {
485             Repr::Os(..) => None,
486             Repr::Simple(..) => None,
487             Repr::Custom(c) => Some(c.error),
488         }
489     }
490
491     /// Returns the corresponding [`ErrorKind`] for this error.
492     ///
493     /// # Examples
494     ///
495     /// ```
496     /// use std::io::{Error, ErrorKind};
497     ///
498     /// fn print_error(err: Error) {
499     ///     println!("{:?}", err.kind());
500     /// }
501     ///
502     /// fn main() {
503     ///     // Will print "Other".
504     ///     print_error(Error::last_os_error());
505     ///     // Will print "AddrInUse".
506     ///     print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
507     /// }
508     /// ```
509     #[stable(feature = "rust1", since = "1.0.0")]
510     pub fn kind(&self) -> ErrorKind {
511         match self.repr {
512             Repr::Os(code) => sys::decode_error_kind(code),
513             Repr::Custom(ref c) => c.kind,
514             Repr::Simple(kind) => kind,
515         }
516     }
517 }
518
519 impl fmt::Debug for Repr {
520     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
521         match *self {
522             Repr::Os(code) => fmt
523                 .debug_struct("Os")
524                 .field("code", &code)
525                 .field("kind", &sys::decode_error_kind(code))
526                 .field("message", &sys::os::error_string(code))
527                 .finish(),
528             Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt),
529             Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
530         }
531     }
532 }
533
534 #[stable(feature = "rust1", since = "1.0.0")]
535 impl fmt::Display for Error {
536     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
537         match self.repr {
538             Repr::Os(code) => {
539                 let detail = sys::os::error_string(code);
540                 write!(fmt, "{} (os error {})", detail, code)
541             }
542             Repr::Custom(ref c) => c.error.fmt(fmt),
543             Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
544         }
545     }
546 }
547
548 #[stable(feature = "rust1", since = "1.0.0")]
549 impl error::Error for Error {
550     #[allow(deprecated, deprecated_in_future)]
551     fn description(&self) -> &str {
552         match self.repr {
553             Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
554             Repr::Custom(ref c) => c.error.description(),
555         }
556     }
557
558     #[allow(deprecated)]
559     fn cause(&self) -> Option<&dyn error::Error> {
560         match self.repr {
561             Repr::Os(..) => None,
562             Repr::Simple(..) => None,
563             Repr::Custom(ref c) => c.error.cause(),
564         }
565     }
566
567     fn source(&self) -> Option<&(dyn error::Error + 'static)> {
568         match self.repr {
569             Repr::Os(..) => None,
570             Repr::Simple(..) => None,
571             Repr::Custom(ref c) => c.error.source(),
572         }
573     }
574 }
575
576 fn _assert_error_is_sync_send() {
577     fn _is_sync_send<T: Sync + Send>() {}
578     _is_sync_send::<Error>();
579 }