From c267404d6d79f15e63f19084f7b0eddc929aff2e Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Wed, 1 Jul 2026 12:28:38 -0500 Subject: [PATCH] Ignore `NA`s when pruning cache files `file.info()` returns `NA` for files that can't be stat'd, which happens when a cache file is deleted between listing and stat'ing it. This propagated into `to_remove`, causing `if (any(to_remove))` to error or corrupt the returned `info`. Now coerce `NA` to `FALSE`. --- NEWS.md | 2 ++ R/req-cache.R | 2 ++ tests/testthat/test-req-cache.R | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index c688be302..46b7d1fd1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # httr2 (development version) +* `req_cache()` pruning no longer errors if a cache file is deleted while the cache is being pruned. + # httr2 1.2.3 * Mocked and cached responses now include the originating request in `resp$request`, just like real responses (#841). diff --git a/R/req-cache.R b/R/req-cache.R index bd0875fb7..0d12ea815 100644 --- a/R/req-cache.R +++ b/R/req-cache.R @@ -191,6 +191,8 @@ cache_info <- function(path, pattern = "\\.rds$") { } cache_prune_files <- function(info, to_remove, why, debug = TRUE) { + to_remove[is.na(to_remove)] <- FALSE + if (any(to_remove)) { if (debug) { cli::cli_text("Deleted {sum(to_remove)} file{?s} that {?is/are} {why}") diff --git a/tests/testthat/test-req-cache.R b/tests/testthat/test-req-cache.R index 787ca5b57..cbc80a23f 100644 --- a/tests/testthat/test-req-cache.R +++ b/tests/testthat/test-req-cache.R @@ -286,6 +286,11 @@ test_that("can prune by size", { expect_equal(dir(path), "c.rds") }) +test_that("cache_prune_files ignores NAs in to_remove", { + info <- data.frame(name = c("a", "b"), size = 1, mtime = Sys.time()) + expect_equal(cache_prune_files(info, c(NA, FALSE), "x", debug = FALSE), info) +}) + # headers ----------------------------------------------------------------- test_that("correctly determines if response is cacheable", {