mirror of https://github.com/rust-lang/rust.git
Handle fs errors through errors::Handler instead of eprintln and panic
This commit is contained in:
parent
6392bc9fcd
commit
3eeb543504
|
@ -3254,6 +3254,7 @@ dependencies = [
|
||||||
"minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
"minifier 0.0.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pulldown-cmark 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pulldown-cmark 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,14 @@
|
||||||
//! needs to read-after-write from a file, then it would be added to this
|
//! needs to read-after-write from a file, then it would be added to this
|
||||||
//! abstraction.
|
//! abstraction.
|
||||||
|
|
||||||
|
use errors;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
|
|
||||||
macro_rules! try_err {
|
macro_rules! try_err {
|
||||||
($e:expr, $file:expr) => {{
|
($e:expr, $file:expr) => {{
|
||||||
|
@ -26,14 +31,45 @@ pub trait PathError {
|
||||||
fn new<P: AsRef<Path>>(e: io::Error, path: P) -> Self;
|
fn new<P: AsRef<Path>>(e: io::Error, path: P) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ErrorStorage {
|
||||||
|
sender: Sender<Option<String>>,
|
||||||
|
receiver: Receiver<Option<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ErrorStorage {
|
||||||
|
pub fn new() -> ErrorStorage {
|
||||||
|
let (sender, receiver) = channel();
|
||||||
|
ErrorStorage {
|
||||||
|
sender,
|
||||||
|
receiver,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints all stored errors. Returns the number of printed errors.
|
||||||
|
pub fn write_errors(&self, diag: &errors::Handler) -> usize {
|
||||||
|
let mut printed = 0;
|
||||||
|
drop(self.sender);
|
||||||
|
|
||||||
|
for msg in self.receiver.iter() {
|
||||||
|
if let Some(ref error) = msg {
|
||||||
|
diag.struct_err(&error).emit();
|
||||||
|
printed += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DocFS {
|
pub struct DocFS {
|
||||||
sync_only: bool,
|
sync_only: bool,
|
||||||
|
errors: Arc<ErrorStorage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DocFS {
|
impl DocFS {
|
||||||
pub fn new() -> DocFS {
|
pub fn new(errors: &Arc<ErrorStorage>) -> DocFS {
|
||||||
DocFS {
|
DocFS {
|
||||||
sync_only: false,
|
sync_only: false,
|
||||||
|
errors: Arc::clone(errors),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +95,17 @@ impl DocFS {
|
||||||
// be to create the file sync so errors are reported eagerly.
|
// be to create the file sync so errors are reported eagerly.
|
||||||
let contents = contents.as_ref().to_vec();
|
let contents = contents.as_ref().to_vec();
|
||||||
let path = path.as_ref().to_path_buf();
|
let path = path.as_ref().to_path_buf();
|
||||||
rayon::spawn(move ||
|
let sender = self.errors.sender.clone();
|
||||||
|
rayon::spawn(move || {
|
||||||
match fs::write(&path, &contents) {
|
match fs::write(&path, &contents) {
|
||||||
Ok(_) => (),
|
Ok(_) => {
|
||||||
|
sender.send(None)
|
||||||
|
.expect(&format!("failed to send error on \"{}\"", path.display()));
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// In principle these should get displayed at the top
|
sender.send(Some(format!("\"{}\": {}", path.display(), e)))
|
||||||
// level, but just in case, send to stderr as well.
|
.expect(&format!("failed to send non-error on \"{}\"", path.display()));
|
||||||
eprintln!("\"{}\": {}", path.display(), e);
|
}
|
||||||
panic!("\"{}\": {}", path.display(), e);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -61,7 +61,7 @@ use rustc_data_structures::flock;
|
||||||
|
|
||||||
use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, Mutability};
|
use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, Mutability};
|
||||||
use crate::config::RenderOptions;
|
use crate::config::RenderOptions;
|
||||||
use crate::docfs::{DocFS, PathError};
|
use crate::docfs::{DocFS, ErrorStorage, PathError};
|
||||||
use crate::doctree;
|
use crate::doctree;
|
||||||
use crate::fold::DocFolder;
|
use crate::fold::DocFolder;
|
||||||
use crate::html::escape::Escape;
|
use crate::html::escape::Escape;
|
||||||
|
@ -104,9 +104,14 @@ impl error::Error for Error {
|
||||||
|
|
||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
let file = self.file.display().to_string();
|
||||||
|
if file.is_empty() {
|
||||||
|
write!(f, "{}", self.error)
|
||||||
|
} else {
|
||||||
write!(f, "\"{}\": {}", self.file.display(), self.error)
|
write!(f, "\"{}\": {}", self.file.display(), self.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PathError for Error {
|
impl PathError for Error {
|
||||||
fn new<P: AsRef<Path>>(e: io::Error, path: P) -> Error {
|
fn new<P: AsRef<Path>>(e: io::Error, path: P) -> Error {
|
||||||
|
@ -547,6 +552,7 @@ pub fn run(mut krate: clean::Crate,
|
||||||
},
|
},
|
||||||
_ => PathBuf::new(),
|
_ => PathBuf::new(),
|
||||||
};
|
};
|
||||||
|
let errors = Arc::new(ErrorStorage::new());
|
||||||
let mut scx = SharedContext {
|
let mut scx = SharedContext {
|
||||||
src_root,
|
src_root,
|
||||||
passes,
|
passes,
|
||||||
|
@ -567,7 +573,7 @@ pub fn run(mut krate: clean::Crate,
|
||||||
static_root_path,
|
static_root_path,
|
||||||
generate_search_filter,
|
generate_search_filter,
|
||||||
generate_redirect_pages,
|
generate_redirect_pages,
|
||||||
fs: DocFS::new(),
|
fs: DocFS::new(&errors),
|
||||||
};
|
};
|
||||||
|
|
||||||
// If user passed in `--playground-url` arg, we fill in crate name here
|
// If user passed in `--playground-url` arg, we fill in crate name here
|
||||||
|
@ -715,7 +721,15 @@ pub fn run(mut krate: clean::Crate,
|
||||||
Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
|
Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
|
||||||
|
|
||||||
// And finally render the whole crate's documentation
|
// And finally render the whole crate's documentation
|
||||||
cx.krate(krate)
|
let ret = cx.krate(krate);
|
||||||
|
let nb_errors = errors.write_errors(diag);
|
||||||
|
if ret.is_err() {
|
||||||
|
ret
|
||||||
|
} else if nb_errors > 0 {
|
||||||
|
Err(Error::new(io::Error::new(io::ErrorKind::Other, "I/O error"), ""))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the search index from the collected metadata
|
/// Builds the search index from the collected metadata
|
||||||
|
|
Loading…
Reference in New Issue