From a5c0958adf9bcc1a4419767ce8f2db3c29bfc99a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 9 Jan 2022 16:33:31 +0000 Subject: [PATCH] Filesystem::safeFilePutContents() now consistently throws RuntimeException in all expected failure cases unexpected cases may still throw ErrorException (such as undefined variables) but we don't want to capture those. --- src/Server.php | 2 +- src/utils/Filesystem.php | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Server.php b/src/Server.php index 9c81023545..48ff558615 100644 --- a/src/Server.php +++ b/src/Server.php @@ -545,7 +545,7 @@ class Server{ $contents = Utils::assumeNotFalse(zlib_encode($nbt->write(new TreeRoot($ev->getSaveData())), ZLIB_ENCODING_GZIP), "zlib_encode() failed unexpectedly"); try{ Filesystem::safeFilePutContents($this->getPlayerDataPath($name), $contents); - }catch(\RuntimeException | \ErrorException $e){ + }catch(\RuntimeException $e){ $this->logger->critical($this->getLanguage()->translate(KnownTranslationFactory::pocketmine_data_saveError($name, $e->getMessage()))); $this->logger->logException($e); } diff --git a/src/utils/Filesystem.php b/src/utils/Filesystem.php index 574338035b..9545bad1a0 100644 --- a/src/utils/Filesystem.php +++ b/src/utils/Filesystem.php @@ -27,7 +27,6 @@ use pocketmine\errorhandler\ErrorToExceptionHandler; use Webmozart\PathUtil\Path; use function copy; use function dirname; -use function disk_free_space; use function fclose; use function fflush; use function file_exists; @@ -236,6 +235,8 @@ final class Filesystem{ * new contents. * * @param resource|null $context Context to pass to file_put_contents + * + * @throws \RuntimeException if the operation failed for any reason */ public static function safeFilePutContents(string $fileName, string $contents, int $flags = 0, $context = null) : void{ $directory = dirname($fileName); @@ -253,19 +254,16 @@ final class Filesystem{ $counter++; }while(is_dir($temporaryFileName)); - $writeTemporaryFileResult = $context !== null ? - file_put_contents($temporaryFileName, $contents, $flags, $context) : - file_put_contents($temporaryFileName, $contents, $flags); - - if($writeTemporaryFileResult !== strlen($contents)){ + try{ + ErrorToExceptionHandler::trap(fn() => $context !== null ? + file_put_contents($temporaryFileName, $contents, $flags, $context) : + file_put_contents($temporaryFileName, $contents, $flags) + ); + }catch(\ErrorException $filePutContentsException){ $context !== null ? @unlink($temporaryFileName, $context) : @unlink($temporaryFileName); - $diskSpace = disk_free_space($directory); - if($diskSpace !== false && $diskSpace < strlen($contents)){ - throw new \RuntimeException("Failed to write to temporary file $temporaryFileName (out of free disk space)"); - } - throw new \RuntimeException("Failed to write to temporary file $temporaryFileName (possibly out of free disk space)"); + throw new \RuntimeException("Failed to write to temporary file $temporaryFileName: " . $filePutContentsException->getMessage(), 0, $filePutContentsException); } $renameTemporaryFileResult = $context !== null ?