summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-03-15 09:57:24 -0400
committerGitHub <noreply@github.com>2024-03-15 09:57:24 -0400
commit36e6e4a00997603d2290c416239c2de8feeb6ede (patch)
treeb6fab810ad3f0264ffd1447e1c039b08e290db6a
parentdae162f7385028aadc5ae893b4d27ad338c88b2c (diff)
fix: handle cache body file not existing when using etag (#22931)
-rw-r--r--cli/file_fetcher.rs22
-rw-r--r--tests/integration/run_tests.rs33
2 files changed, 52 insertions, 3 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index a74a14a3f..3808d68ce 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -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, &[])?;
diff --git a/tests/integration/run_tests.rs b/tests/integration/run_tests.rs
index 1d46cd249..59163bfe8 100644
--- a/tests/integration/run_tests.rs
+++ b/tests/integration/run_tests.rs
@@ -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]",
+ );
+}