]> git.lizzy.rs Git - rust.git/blob - library/core/src/error.rs
37bd19c6f03c406d2014f3cfb6f092aa98b9d90c
[rust.git] / library / core / src / error.rs
1 #![doc = include_str!("error.md")]
2 #![unstable(feature = "error_in_core", issue = "none")]
3
4 // A note about crates and the facade:
5 //
6 // Originally, the `Error` trait was defined in libcore, and the impls
7 // were scattered about. However, coherence objected to this
8 // arrangement, because to create the blanket impls for `Box` required
9 // knowing that `&str: !Error`, and we have no means to deal with that
10 // sort of conflict just now. Therefore, for the time being, we have
11 // moved the `Error` trait into libstd. As we evolve a sol'n to the
12 // coherence challenge (e.g., specialization, neg impls, etc) we can
13 // reconsider what crate these items belong in.
14
15 #[cfg(test)]
16 mod tests;
17
18 use crate::any::{Demand, Provider, TypeId};
19 use crate::fmt::{Debug, Display};
20
21 /// `Error` is a trait representing the basic expectations for error values,
22 /// i.e., values of type `E` in [`Result<T, E>`].
23 ///
24 /// Errors must describe themselves through the [`Display`] and [`Debug`]
25 /// traits. Error messages are typically concise lowercase sentences without
26 /// trailing punctuation:
27 ///
28 /// ```
29 /// let err = "NaN".parse::<u32>().unwrap_err();
30 /// assert_eq!(err.to_string(), "invalid digit found in string");
31 /// ```
32 ///
33 /// Errors may provide cause information. [`Error::source()`] is generally
34 /// used when errors cross "abstraction boundaries". If one module must report
35 /// an error that is caused by an error from a lower-level module, it can allow
36 /// accessing that error via [`Error::source()`]. This makes it possible for the
37 /// high-level module to provide its own errors while also revealing some of the
38 /// implementation for debugging.
39 #[stable(feature = "rust1", since = "1.0.0")]
40 #[cfg_attr(not(test), rustc_diagnostic_item = "Error")]
41 #[rustc_has_incoherent_inherent_impls]
42 pub trait Error: Debug + Display {
43     /// The lower-level source of this error, if any.
44     ///
45     /// # Examples
46     ///
47     /// ```
48     /// use std::error::Error;
49     /// use std::fmt;
50     ///
51     /// #[derive(Debug)]
52     /// struct SuperError {
53     ///     source: SuperErrorSideKick,
54     /// }
55     ///
56     /// impl fmt::Display for SuperError {
57     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58     ///         write!(f, "SuperError is here!")
59     ///     }
60     /// }
61     ///
62     /// impl Error for SuperError {
63     ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
64     ///         Some(&self.source)
65     ///     }
66     /// }
67     ///
68     /// #[derive(Debug)]
69     /// struct SuperErrorSideKick;
70     ///
71     /// impl fmt::Display for SuperErrorSideKick {
72     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73     ///         write!(f, "SuperErrorSideKick is here!")
74     ///     }
75     /// }
76     ///
77     /// impl Error for SuperErrorSideKick {}
78     ///
79     /// fn get_super_error() -> Result<(), SuperError> {
80     ///     Err(SuperError { source: SuperErrorSideKick })
81     /// }
82     ///
83     /// fn main() {
84     ///     match get_super_error() {
85     ///         Err(e) => {
86     ///             println!("Error: {e}");
87     ///             println!("Caused by: {}", e.source().unwrap());
88     ///         }
89     ///         _ => println!("No error"),
90     ///     }
91     /// }
92     /// ```
93     #[stable(feature = "error_source", since = "1.30.0")]
94     fn source(&self) -> Option<&(dyn Error + 'static)> {
95         None
96     }
97
98     /// Gets the `TypeId` of `self`.
99     #[doc(hidden)]
100     #[unstable(
101         feature = "error_type_id",
102         reason = "this is memory-unsafe to override in user code",
103         issue = "60784"
104     )]
105     fn type_id(&self, _: private::Internal) -> TypeId
106     where
107         Self: 'static,
108     {
109         TypeId::of::<Self>()
110     }
111
112     /// ```
113     /// if let Err(e) = "xc".parse::<u32>() {
114     ///     // Print `e` itself, no need for description().
115     ///     eprintln!("Error: {e}");
116     /// }
117     /// ```
118     #[stable(feature = "rust1", since = "1.0.0")]
119     #[deprecated(since = "1.42.0", note = "use the Display impl or to_string()")]
120     fn description(&self) -> &str {
121         "description() is deprecated; use Display"
122     }
123
124     #[stable(feature = "rust1", since = "1.0.0")]
125     #[deprecated(
126         since = "1.33.0",
127         note = "replaced by Error::source, which can support downcasting"
128     )]
129     #[allow(missing_docs)]
130     fn cause(&self) -> Option<&dyn Error> {
131         self.source()
132     }
133
134     /// Provides type based access to context intended for error reports.
135     ///
136     /// Used in conjunction with [`Demand::provide_value`] and [`Demand::provide_ref`] to extract
137     /// references to member variables from `dyn Error` trait objects.
138     ///
139     /// # Example
140     ///
141     /// ```rust
142     /// #![feature(provide_any)]
143     /// #![feature(error_generic_member_access)]
144     /// use core::fmt;
145     /// use core::any::Demand;
146     ///
147     /// #[derive(Debug)]
148     /// struct MyBacktrace {
149     ///     // ...
150     /// }
151     ///
152     /// impl MyBacktrace {
153     ///     fn new() -> MyBacktrace {
154     ///         // ...
155     ///         # MyBacktrace {}
156     ///     }
157     /// }
158     ///
159     /// #[derive(Debug)]
160     /// struct SourceError {
161     ///     // ...
162     /// }
163     ///
164     /// impl fmt::Display for SourceError {
165     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166     ///         write!(f, "Example Source Error")
167     ///     }
168     /// }
169     ///
170     /// impl std::error::Error for SourceError {}
171     ///
172     /// #[derive(Debug)]
173     /// struct Error {
174     ///     source: SourceError,
175     ///     backtrace: MyBacktrace,
176     /// }
177     ///
178     /// impl fmt::Display for Error {
179     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180     ///         write!(f, "Example Error")
181     ///     }
182     /// }
183     ///
184     /// impl std::error::Error for Error {
185     ///     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
186     ///         req
187     ///             .provide_ref::<MyBacktrace>(&self.backtrace)
188     ///             .provide_ref::<dyn std::error::Error + 'static>(&self.source);
189     ///     }
190     /// }
191     ///
192     /// fn main() {
193     ///     let backtrace = MyBacktrace::new();
194     ///     let source = SourceError {};
195     ///     let error = Error { source, backtrace };
196     ///     let dyn_error = &error as &dyn std::error::Error;
197     ///     let backtrace_ref = dyn_error.request_ref::<MyBacktrace>().unwrap();
198     ///
199     ///     assert!(core::ptr::eq(&error.backtrace, backtrace_ref));
200     /// }
201     /// ```
202     #[unstable(feature = "error_generic_member_access", issue = "99301")]
203     #[allow(unused_variables)]
204     fn provide<'a>(&'a self, req: &mut Demand<'a>) {}
205 }
206
207 #[unstable(feature = "error_generic_member_access", issue = "99301")]
208 impl<E> Provider for E
209 where
210     E: Error + ?Sized,
211 {
212     fn provide<'a>(&'a self, req: &mut Demand<'a>) {
213         self.provide(req)
214     }
215 }
216
217 mod private {
218     // This is a hack to prevent `type_id` from being overridden by `Error`
219     // implementations, since that can enable unsound downcasting.
220     #[unstable(feature = "error_type_id", issue = "60784")]
221     #[derive(Debug)]
222     pub struct Internal;
223 }
224
225 #[unstable(feature = "never_type", issue = "35121")]
226 impl Error for ! {}
227
228 impl<'a> dyn Error + 'a {
229     /// Request a reference of type `T` as context about this error.
230     #[unstable(feature = "error_generic_member_access", issue = "99301")]
231     pub fn request_ref<T: ?Sized + 'static>(&'a self) -> Option<&'a T> {
232         core::any::request_ref(self)
233     }
234
235     /// Request a value of type `T` as context about this error.
236     #[unstable(feature = "error_generic_member_access", issue = "99301")]
237     pub fn request_value<T: 'static>(&'a self) -> Option<T> {
238         core::any::request_value(self)
239     }
240 }
241
242 // Copied from `any.rs`.
243 impl dyn Error + 'static {
244     /// Returns `true` if the inner type is the same as `T`.
245     #[stable(feature = "error_downcast", since = "1.3.0")]
246     #[inline]
247     pub fn is<T: Error + 'static>(&self) -> bool {
248         // Get `TypeId` of the type this function is instantiated with.
249         let t = TypeId::of::<T>();
250
251         // Get `TypeId` of the type in the trait object (`self`).
252         let concrete = self.type_id(private::Internal);
253
254         // Compare both `TypeId`s on equality.
255         t == concrete
256     }
257
258     /// Returns some reference to the inner value if it is of type `T`, or
259     /// `None` if it isn't.
260     #[stable(feature = "error_downcast", since = "1.3.0")]
261     #[inline]
262     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
263         if self.is::<T>() {
264             // SAFETY: `is` ensures this type cast is correct
265             unsafe { Some(&*(self as *const dyn Error as *const T)) }
266         } else {
267             None
268         }
269     }
270
271     /// Returns some mutable reference to the inner value if it is of type `T`, or
272     /// `None` if it isn't.
273     #[stable(feature = "error_downcast", since = "1.3.0")]
274     #[inline]
275     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
276         if self.is::<T>() {
277             // SAFETY: `is` ensures this type cast is correct
278             unsafe { Some(&mut *(self as *mut dyn Error as *mut T)) }
279         } else {
280             None
281         }
282     }
283 }
284
285 impl dyn Error + 'static + Send {
286     /// Forwards to the method defined on the type `dyn Error`.
287     #[stable(feature = "error_downcast", since = "1.3.0")]
288     #[inline]
289     pub fn is<T: Error + 'static>(&self) -> bool {
290         <dyn Error + 'static>::is::<T>(self)
291     }
292
293     /// Forwards to the method defined on the type `dyn Error`.
294     #[stable(feature = "error_downcast", since = "1.3.0")]
295     #[inline]
296     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
297         <dyn Error + 'static>::downcast_ref::<T>(self)
298     }
299
300     /// Forwards to the method defined on the type `dyn Error`.
301     #[stable(feature = "error_downcast", since = "1.3.0")]
302     #[inline]
303     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
304         <dyn Error + 'static>::downcast_mut::<T>(self)
305     }
306
307     /// Request a reference of type `T` as context about this error.
308     #[unstable(feature = "error_generic_member_access", issue = "99301")]
309     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
310         <dyn Error>::request_ref(self)
311     }
312
313     /// Request a value of type `T` as context about this error.
314     #[unstable(feature = "error_generic_member_access", issue = "99301")]
315     pub fn request_value<T: 'static>(&self) -> Option<T> {
316         <dyn Error>::request_value(self)
317     }
318 }
319
320 impl dyn Error + 'static + Send + Sync {
321     /// Forwards to the method defined on the type `dyn Error`.
322     #[stable(feature = "error_downcast", since = "1.3.0")]
323     #[inline]
324     pub fn is<T: Error + 'static>(&self) -> bool {
325         <dyn Error + 'static>::is::<T>(self)
326     }
327
328     /// Forwards to the method defined on the type `dyn Error`.
329     #[stable(feature = "error_downcast", since = "1.3.0")]
330     #[inline]
331     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
332         <dyn Error + 'static>::downcast_ref::<T>(self)
333     }
334
335     /// Forwards to the method defined on the type `dyn Error`.
336     #[stable(feature = "error_downcast", since = "1.3.0")]
337     #[inline]
338     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
339         <dyn Error + 'static>::downcast_mut::<T>(self)
340     }
341
342     /// Request a reference of type `T` as context about this error.
343     #[unstable(feature = "error_generic_member_access", issue = "99301")]
344     pub fn request_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
345         <dyn Error>::request_ref(self)
346     }
347
348     /// Request a value of type `T` as context about this error.
349     #[unstable(feature = "error_generic_member_access", issue = "99301")]
350     pub fn request_value<T: 'static>(&self) -> Option<T> {
351         <dyn Error>::request_value(self)
352     }
353 }
354
355 impl dyn Error {
356     /// Returns an iterator starting with the current error and continuing with
357     /// recursively calling [`Error::source`].
358     ///
359     /// If you want to omit the current error and only use its sources,
360     /// use `skip(1)`.
361     ///
362     /// # Examples
363     ///
364     /// ```
365     /// #![feature(error_iter)]
366     /// use std::error::Error;
367     /// use std::fmt;
368     ///
369     /// #[derive(Debug)]
370     /// struct A;
371     ///
372     /// #[derive(Debug)]
373     /// struct B(Option<Box<dyn Error + 'static>>);
374     ///
375     /// impl fmt::Display for A {
376     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
377     ///         write!(f, "A")
378     ///     }
379     /// }
380     ///
381     /// impl fmt::Display for B {
382     ///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
383     ///         write!(f, "B")
384     ///     }
385     /// }
386     ///
387     /// impl Error for A {}
388     ///
389     /// impl Error for B {
390     ///     fn source(&self) -> Option<&(dyn Error + 'static)> {
391     ///         self.0.as_ref().map(|e| e.as_ref())
392     ///     }
393     /// }
394     ///
395     /// let b = B(Some(Box::new(A)));
396     ///
397     /// // let err : Box<Error> = b.into(); // or
398     /// let err = &b as &(dyn Error);
399     ///
400     /// let mut iter = err.sources();
401     ///
402     /// assert_eq!("B".to_string(), iter.next().unwrap().to_string());
403     /// assert_eq!("A".to_string(), iter.next().unwrap().to_string());
404     /// assert!(iter.next().is_none());
405     /// assert!(iter.next().is_none());
406     /// ```
407     #[unstable(feature = "error_iter", issue = "58520")]
408     #[inline]
409     pub fn sources(&self) -> Source<'_> {
410         // You may think this method would be better in the Error trait, and you'd be right.
411         // Unfortunately that doesn't work, not because of the object safety rules but because we
412         // save a reference to self in Sources below as a trait object. If this method was
413         // declared in Error, then self would have the type &T where T is some concrete type which
414         // implements Error. We would need to coerce self to have type &dyn Error, but that requires
415         // that Self has a known size (i.e., Self: Sized). We can't put that bound on Error
416         // since that would forbid Error trait objects, and we can't put that bound on the method
417         // because that means the method can't be called on trait objects (we'd also need the
418         // 'static bound, but that isn't allowed because methods with bounds on Self other than
419         // Sized are not object-safe). Requiring an Unsize bound is not backwards compatible.
420         //
421         // Two possible solutions are to start the iterator at self.source() instead of self (see
422         // discussion on the tracking issue), or to wait for dyn* to exist (which would then permit
423         // the coercion).
424
425         Source { current: Some(self) }
426     }
427 }
428
429 /// An iterator over an [`Error`] and its sources.
430 ///
431 /// If you want to omit the initial error and only process
432 /// its sources, use `skip(1)`.
433 #[unstable(feature = "error_iter", issue = "58520")]
434 #[derive(Clone, Debug)]
435 pub struct Source<'a> {
436     current: Option<&'a (dyn Error + 'static)>,
437 }
438
439 #[unstable(feature = "error_iter", issue = "58520")]
440 impl<'a> Iterator for Source<'a> {
441     type Item = &'a (dyn Error + 'static);
442
443     fn next(&mut self) -> Option<Self::Item> {
444         let current = self.current;
445         self.current = self.current.and_then(Error::source);
446         current
447     }
448 }
449
450 #[stable(feature = "error_by_ref", since = "1.51.0")]
451 impl<'a, T: Error + ?Sized> Error for &'a T {
452     #[allow(deprecated, deprecated_in_future)]
453     fn description(&self) -> &str {
454         Error::description(&**self)
455     }
456
457     #[allow(deprecated)]
458     fn cause(&self) -> Option<&dyn Error> {
459         Error::cause(&**self)
460     }
461
462     fn source(&self) -> Option<&(dyn Error + 'static)> {
463         Error::source(&**self)
464     }
465
466     fn provide<'b>(&'b self, req: &mut Demand<'b>) {
467         Error::provide(&**self, req);
468     }
469 }
470
471 #[stable(feature = "fmt_error", since = "1.11.0")]
472 impl Error for crate::fmt::Error {
473     #[allow(deprecated)]
474     fn description(&self) -> &str {
475         "an error occurred when formatting an argument"
476     }
477 }
478
479 #[stable(feature = "try_borrow", since = "1.13.0")]
480 impl Error for crate::cell::BorrowError {
481     #[allow(deprecated)]
482     fn description(&self) -> &str {
483         "already mutably borrowed"
484     }
485 }
486
487 #[stable(feature = "try_borrow", since = "1.13.0")]
488 impl Error for crate::cell::BorrowMutError {
489     #[allow(deprecated)]
490     fn description(&self) -> &str {
491         "already borrowed"
492     }
493 }
494
495 #[stable(feature = "try_from", since = "1.34.0")]
496 impl Error for crate::char::CharTryFromError {
497     #[allow(deprecated)]
498     fn description(&self) -> &str {
499         "converted integer out of range for `char`"
500     }
501 }
502
503 #[stable(feature = "char_from_str", since = "1.20.0")]
504 impl Error for crate::char::ParseCharError {
505     #[allow(deprecated)]
506     fn description(&self) -> &str {
507         self.__description()
508     }
509 }
510
511 #[unstable(feature = "duration_checked_float", issue = "83400")]
512 impl Error for crate::time::FromFloatSecsError {}
513
514 #[stable(feature = "frombyteswithnulerror_impls", since = "1.17.0")]
515 impl Error for crate::ffi::FromBytesWithNulError {
516     #[allow(deprecated)]
517     fn description(&self) -> &str {
518         self.__description()
519     }
520 }
521
522 #[unstable(feature = "cstr_from_bytes_until_nul", issue = "95027")]
523 impl Error for crate::ffi::FromBytesUntilNulError {}