Do not panic and improve error message on cache failure (#3784)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2020-01-24 14:16:31 -08:00 committed by Ryan Dahl
parent 5e32c5ea44
commit 514cdd941c
2 changed files with 60 additions and 18 deletions

View file

@ -13,6 +13,13 @@ pub struct DiskCache {
pub location: PathBuf, pub location: PathBuf,
} }
fn with_io_context<T: AsRef<str>>(
e: &std::io::Error,
context: T,
) -> std::io::Error {
std::io::Error::new(e.kind(), format!("{} (for '{}')", e, context.as_ref()))
}
impl DiskCache { impl DiskCache {
pub fn new(location: &Path) -> Self { pub fn new(location: &Path) -> Self {
// TODO: ensure that 'location' is a directory // TODO: ensure that 'location' is a directory
@ -107,10 +114,12 @@ impl DiskCache {
pub fn set(&self, filename: &Path, data: &[u8]) -> std::io::Result<()> { pub fn set(&self, filename: &Path, data: &[u8]) -> std::io::Result<()> {
let path = self.location.join(filename); let path = self.location.join(filename);
match path.parent() { match path.parent() {
Some(ref parent) => fs::create_dir_all(parent), Some(ref parent) => fs::create_dir_all(parent)
.map_err(|e| with_io_context(&e, format!("{:#?}", &path))),
None => Ok(()), None => Ok(()),
}?; }?;
deno_fs::write_file(&path, data, 0o666) deno_fs::write_file(&path, data, 0o666)
.map_err(|e| with_io_context(&e, format!("{:#?}", &path)))
} }
pub fn remove(&self, filename: &Path) -> std::io::Result<()> { pub fn remove(&self, filename: &Path) -> std::io::Result<()> {

View file

@ -28,6 +28,28 @@ use std::sync::Mutex;
use url; use url;
use url::Url; use url::Url;
pub fn source_header_cache_failed_error(
module_name: &str,
reason: &str,
) -> ErrBox {
DenoError::new(
ErrorKind::Other,
format!(
"Source code header cache failed for '{}': {}",
module_name, reason
),
)
.into()
}
pub fn source_cache_failed_error(module_name: &str, reason: &str) -> ErrBox {
DenoError::new(
ErrorKind::Other,
format!("Source code cache failed for '{}': {}", module_name, reason),
)
.into()
}
/// Structure representing local or remote file. /// Structure representing local or remote file.
/// ///
/// In case of remote file `url` might be different than originally requested URL, if so /// In case of remote file `url` might be different than originally requested URL, if so
@ -416,14 +438,17 @@ impl SourceFileFetcher {
} }
FetchOnceResult::Redirect(new_module_url) => { FetchOnceResult::Redirect(new_module_url) => {
// If redirects, update module_name and filename for next looped call. // If redirects, update module_name and filename for next looped call.
dir if let Err(e) = dir.save_source_code_headers(
.save_source_code_headers( &module_url,
&module_url, None,
None, Some(new_module_url.to_string()),
Some(new_module_url.to_string()), None,
None, ) {
) return Err(source_header_cache_failed_error(
.unwrap(); module_url.as_str(),
&e.to_string(),
));
}
// Explicit drop to keep reference alive until future completes. // Explicit drop to keep reference alive until future completes.
drop(download_job); drop(download_job);
@ -440,16 +465,24 @@ impl SourceFileFetcher {
} }
FetchOnceResult::Code(source, maybe_content_type, etag) => { FetchOnceResult::Code(source, maybe_content_type, etag) => {
// We land on the code. // We land on the code.
dir if let Err(e) = dir.save_source_code_headers(
.save_source_code_headers( &module_url,
&module_url, maybe_content_type.clone(),
maybe_content_type.clone(), None,
None, etag,
etag, ) {
) return Err(source_header_cache_failed_error(
.unwrap(); module_url.as_str(),
&e.to_string(),
));
}
dir.save_source_code(&module_url, &source).unwrap(); if let Err(e) = dir.save_source_code(&module_url, &source) {
return Err(source_cache_failed_error(
module_url.as_str(),
&e.to_string(),
));
}
let filepath = dir let filepath = dir
.deps_cache .deps_cache