[2.x] fix: handle NoSuchFileException during cache storage (#8699)

This commit is contained in:
calm 2026-02-06 05:36:07 -06:00 committed by GitHub
parent 52bc35e3a9
commit c4a88328da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 36 additions and 30 deletions

View File

@ -10,7 +10,7 @@ package sbt.util
import java.io.File import java.io.File
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.nio.file.{ Files, Path, Paths, StandardCopyOption } import java.nio.file.{ Files, NoSuchFileException, Path, Paths, StandardCopyOption }
import sbt.internal.util.{ ActionCacheEvent, CacheEventLog, StringVirtualFile1 } import sbt.internal.util.{ ActionCacheEvent, CacheEventLog, StringVirtualFile1 }
import sbt.io.syntax.* import sbt.io.syntax.*
import sbt.io.IO import sbt.io.IO
@ -81,34 +81,40 @@ object ActionCache:
case e: Exception => case e: Exception =>
cacheEventLog.append(ActionCacheEvent.Error) cacheEventLog.append(ActionCacheEvent.Error)
throw e throw e
val json = Converter.toJsonUnsafe(result) try
val normalizedOutputDir = outputDirectory.toAbsolutePath.normalize() val json = Converter.toJsonUnsafe(result)
val uncacheableOutputs = val normalizedOutputDir = outputDirectory.toAbsolutePath.normalize()
outputs.filter(f => val uncacheableOutputs =
f match outputs.filter(f =>
case vf if vf.id.endsWith(ActionCache.dirZipExt) => f match
false case vf if vf.id.endsWith(ActionCache.dirZipExt) =>
case _ => false
val outputPath = fileConverter.toPath(f).toAbsolutePath.normalize() case _ =>
!outputPath.startsWith(normalizedOutputDir) val outputPath = fileConverter.toPath(f).toAbsolutePath.normalize()
) !outputPath.startsWith(normalizedOutputDir)
if uncacheableOutputs.nonEmpty then )
cacheEventLog.append(ActionCacheEvent.Error) if uncacheableOutputs.nonEmpty then
logger.error( cacheEventLog.append(ActionCacheEvent.Error)
s"Cannot cache task because its output files are outside the output directory: \n" + logger.error(
uncacheableOutputs.mkString(" - ", "\n - ", "") s"Cannot cache task because its output files are outside the output directory: \n" +
) uncacheableOutputs.mkString(" - ", "\n - ", "")
result )
else result
cacheEventLog.append(ActionCacheEvent.OnsiteTask) else
val (input, valuePath) = mkInput(key, codeContentHash, extraHash) cacheEventLog.append(ActionCacheEvent.OnsiteTask)
val valueFile = StringVirtualFile1(valuePath, CompactPrinter(json)) val (input, valuePath) = mkInput(key, codeContentHash, extraHash)
val newOutputs = Vector(valueFile) ++ outputs.toVector val valueFile = StringVirtualFile1(valuePath, CompactPrinter(json))
store.put(UpdateActionResultRequest(input, newOutputs, exitCode = 0)) match val newOutputs = Vector(valueFile) ++ outputs.toVector
case Right(cachedResult) => store.put(UpdateActionResultRequest(input, newOutputs, exitCode = 0)) match
store.syncBlobs(cachedResult.outputFiles, outputDirectory) case Right(cachedResult) =>
result store.syncBlobs(cachedResult.outputFiles, outputDirectory)
case Left(e) => throw e result
case Left(e) => throw e
catch
case e: NoSuchFileException =>
logger.debug(s"Skipping cache storage due to missing file: ${e.getMessage}")
cacheEventLog.append(ActionCacheEvent.Error)
result
// Single cache lookup - use exitCode to distinguish success from failure // Single cache lookup - use exitCode to distinguish success from failure
getWithFailure(key, codeContentHash, extraHash, tags, config) match getWithFailure(key, codeContentHash, extraHash, tags, config) match

View File

@ -74,6 +74,6 @@ trait CacheImplicits extends BasicCacheImplicits with BasicJsonProtocol:
val lastModified = attrs.lastModifiedTime().toMillis() val lastModified = attrs.lastModifiedTime().toMillis()
val sizeBytes = attrs.size() val sizeBytes = attrs.size()
getOrElseUpdate(ref, lastModified, sizeBytes)(fallback) getOrElseUpdate(ref, lastModified, sizeBytes)(fallback)
catch case _: NoSuchFileException => fallback catch case e: NoSuchFileException => throw e
case _ => fallback case _ => fallback
end CacheImplicits end CacheImplicits