mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-09-30 06:21:52 +00:00
Detect nightly and only expose backtrace if available
This commit is contained in:
parent
3cd72734d5
commit
270ea5e7d5
39
build.rs
Normal file
39
build.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let compiler = match rustc_version() {
|
||||||
|
Some(compiler) => compiler,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
if compiler.nightly {
|
||||||
|
println!("cargo:rustc-cfg=backtrace");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Compiler {
|
||||||
|
nightly: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rustc_version() -> Option<Compiler> {
|
||||||
|
let rustc = match env::var_os("RUSTC") {
|
||||||
|
Some(rustc) => rustc,
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let output = match Command::new(rustc).arg("--version").output() {
|
||||||
|
Ok(output) => output,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let version = match str::from_utf8(&output.stdout) {
|
||||||
|
Ok(version) => version,
|
||||||
|
Err(_) => return None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(Compiler {
|
||||||
|
nightly: version.contains("nightly") || version.contains("dev"),
|
||||||
|
})
|
||||||
|
}
|
@ -1,8 +1,9 @@
|
|||||||
use std::backtrace::Backtrace;
|
use crate::Error;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt::{self, Debug, Display};
|
use std::fmt::{self, Debug, Display};
|
||||||
|
|
||||||
use crate::Error;
|
#[cfg(backtrace)]
|
||||||
|
use std::backtrace::Backtrace;
|
||||||
|
|
||||||
/// Provides the `context` method for `Result`.
|
/// Provides the `context` method for `Result`.
|
||||||
pub trait Context<T, E> {
|
pub trait Context<T, E> {
|
||||||
@ -89,6 +90,7 @@ where
|
|||||||
E: StdError + 'static,
|
E: StdError + 'static,
|
||||||
C: Display,
|
C: Display,
|
||||||
{
|
{
|
||||||
|
#[cfg(backtrace)]
|
||||||
fn backtrace(&self) -> Option<&Backtrace> {
|
fn backtrace(&self) -> Option<&Backtrace> {
|
||||||
self.error.backtrace()
|
self.error.backtrace()
|
||||||
}
|
}
|
||||||
@ -102,6 +104,7 @@ impl<C> StdError for ContextError<Error, C>
|
|||||||
where
|
where
|
||||||
C: Display,
|
C: Display,
|
||||||
{
|
{
|
||||||
|
#[cfg(backtrace)]
|
||||||
fn backtrace(&self) -> Option<&Backtrace> {
|
fn backtrace(&self) -> Option<&Backtrace> {
|
||||||
Some(self.error.backtrace())
|
Some(self.error.backtrace())
|
||||||
}
|
}
|
||||||
|
16
src/error.rs
16
src/error.rs
@ -1,12 +1,14 @@
|
|||||||
use crate::context::ContextError;
|
use crate::context::ContextError;
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::backtrace::{Backtrace, BacktraceStatus};
|
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt::{self, Debug, Display};
|
use std::fmt::{self, Debug, Display};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
#[cfg(backtrace)]
|
||||||
|
use std::backtrace::{Backtrace, BacktraceStatus};
|
||||||
|
|
||||||
/// The `Error` type, a wrapper around a dynamic error type.
|
/// The `Error` type, a wrapper around a dynamic error type.
|
||||||
///
|
///
|
||||||
/// `Error` functions a lot like `Box<dyn std::error::Error>`, with these
|
/// `Error` functions a lot like `Box<dyn std::error::Error>`, with these
|
||||||
@ -48,6 +50,7 @@ impl Error {
|
|||||||
where
|
where
|
||||||
E: StdError + Send + Sync + 'static,
|
E: StdError + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
|
#[cfg(backtrace)]
|
||||||
let backtrace = match error.backtrace() {
|
let backtrace = match error.backtrace() {
|
||||||
Some(_) => None,
|
Some(_) => None,
|
||||||
None => Some(Backtrace::capture()),
|
None => Some(Backtrace::capture()),
|
||||||
@ -59,6 +62,7 @@ impl Error {
|
|||||||
let inner = Box::new(ErrorImpl {
|
let inner = Box::new(ErrorImpl {
|
||||||
vtable,
|
vtable,
|
||||||
type_id,
|
type_id,
|
||||||
|
#[cfg(backtrace)]
|
||||||
backtrace,
|
backtrace,
|
||||||
error,
|
error,
|
||||||
});
|
});
|
||||||
@ -90,6 +94,12 @@ impl Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the backtrace for this Error.
|
/// Get the backtrace for this Error.
|
||||||
|
///
|
||||||
|
/// Backtraces are only available on the nightly channel. Tracking issue:
|
||||||
|
/// [rust-lang/rust#53487][tracking].
|
||||||
|
///
|
||||||
|
/// [tracking]: https://github.com/rust-lang/rust/issues/53487
|
||||||
|
#[cfg(backtrace)]
|
||||||
pub fn backtrace(&self) -> &Backtrace {
|
pub fn backtrace(&self) -> &Backtrace {
|
||||||
// NB: this unwrap can only fail if the underlying error's backtrace
|
// NB: this unwrap can only fail if the underlying error's backtrace
|
||||||
// method is nondeterministic, which would only happen in maliciously
|
// method is nondeterministic, which would only happen in maliciously
|
||||||
@ -197,6 +207,8 @@ impl Debug for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(backtrace)]
|
||||||
|
{
|
||||||
let backtrace = self.backtrace();
|
let backtrace = self.backtrace();
|
||||||
match backtrace.status() {
|
match backtrace.status() {
|
||||||
BacktraceStatus::Captured => {
|
BacktraceStatus::Captured => {
|
||||||
@ -210,6 +222,7 @@ impl Debug for Error {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -235,6 +248,7 @@ impl Drop for Error {
|
|||||||
struct ErrorImpl<E> {
|
struct ErrorImpl<E> {
|
||||||
vtable: *const (),
|
vtable: *const (),
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
|
#[cfg(backtrace)]
|
||||||
backtrace: Option<Backtrace>,
|
backtrace: Option<Backtrace>,
|
||||||
error: E,
|
error: E,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![feature(backtrace)]
|
#![cfg_attr(backtrace, feature(backtrace))]
|
||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
mod error;
|
mod error;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user