mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
fix: handle cache body file not existing when using etag (#22931)
This commit is contained in:
parent
dae162f738
commit
36e6e4a009
2 changed files with 52 additions and 3 deletions
|
@ -14,6 +14,7 @@ use crate::util::progress_bar::ProgressBar;
|
|||
use crate::util::progress_bar::UpdateGuard;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::generic_error;
|
||||
|
@ -372,6 +373,7 @@ impl FileFetcher {
|
|||
}
|
||||
|
||||
async move {
|
||||
let mut maybe_etag = maybe_etag;
|
||||
let mut retried = false;
|
||||
let result = loop {
|
||||
let result = match fetch_once(
|
||||
|
@ -388,9 +390,23 @@ impl FileFetcher {
|
|||
{
|
||||
FetchOnceResult::NotModified => {
|
||||
let file = file_fetcher
|
||||
.fetch_cached(&specifier, maybe_checksum, 10)?
|
||||
.unwrap();
|
||||
Ok(file)
|
||||
.fetch_cached(&specifier, maybe_checksum.clone(), 10)?;
|
||||
match file {
|
||||
Some(file) => Ok(file),
|
||||
None => {
|
||||
// Someone may have deleted the body from the cache since
|
||||
// it's currently stored in a separate file from the headers,
|
||||
// so delete the etag and try again
|
||||
if maybe_etag.is_some() {
|
||||
debug!("Cache body not found. Trying again without etag.");
|
||||
maybe_etag = None;
|
||||
continue;
|
||||
} else {
|
||||
// should never happen
|
||||
bail!("Your deno cache directory is in an unrecoverable state. Please delete it and try again.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FetchOnceResult::Redirect(redirect_url, headers) => {
|
||||
file_fetcher.http_cache.set(&specifier, headers, &[])?;
|
||||
|
|
|
@ -5137,3 +5137,36 @@ console.log(add(3, 4));
|
|||
let output = test_context.new_command().args("run main.ts").run();
|
||||
output.assert_matches_text("[WILDCARD]5\n7\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_etag_delete_source_cache() {
|
||||
let test_context = TestContextBuilder::new()
|
||||
.use_temp_cwd()
|
||||
.use_http_server()
|
||||
.build();
|
||||
test_context
|
||||
.temp_dir()
|
||||
.write("main.ts", "import 'http://localhost:4545/etag_script.ts'");
|
||||
test_context
|
||||
.new_command()
|
||||
.args("cache main.ts")
|
||||
.run()
|
||||
.skip_output_check();
|
||||
|
||||
// The cache is currently stored unideally in two files where one file has the headers
|
||||
// and the other contains the body. An issue can happen with the etag header where the
|
||||
// headers file exists, but the body was deleted. We need to get the cache to gracefully
|
||||
// handle this scenario.
|
||||
let deno_dir = test_context.deno_dir().path();
|
||||
let etag_script_path = deno_dir.join("deps/http/localhost_PORT4545/26110db7d42c9bad32386735cbc05c301f83e4393963deb8da14fec3b4202a13");
|
||||
assert!(etag_script_path.exists());
|
||||
etag_script_path.remove_file();
|
||||
|
||||
test_context
|
||||
.new_command()
|
||||
.args("cache --reload --log-level=debug main.ts")
|
||||
.run()
|
||||
.assert_matches_text(
|
||||
"[WILDCARD]Cache body not found. Trying again without etag.[WILDCARD]",
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue