8000 [Filesystem] improve error handling in lock() · symfony/symfony@5bd2d35 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5bd2d35

Browse files
committed
[Filesystem] improve error handling in lock()
1 parent 49d6604 commit 5bd2d35

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

src/Symfony/Component/Filesystem/LockHandler.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,12 @@ public function lock($blocking = false)
6868
return true;
6969
}
7070

71+
$error = null;
72+
7173
// Silence error reporting
72-
set_error_handler(function () {});
74+
set_error_handler(function ($errno, $msg) use (&$error) {
75+
$error = $msg;
76+
});
7377

7478
if (!$this->handle = fopen($this->file, 'r')) {
7579
if ($this->handle = fopen($this->file, 'x')) {
@@ -82,8 +86,12 @@ public function lock($blocking = false)
8286
restore_error_handler();
8387

8488
if (!$this->handle) {
85-
$error = error_get_last();
86-
throw new IOException($error['message'], 0, null, $this->file);
89+
if (null === $error) {
90+
$lastError = error_get_last();
91+
$error = $lastError['message'];
92+
}
93+
94+
throw new IOException($error, 0, null, $this->file);
8795
}
8896

8997
// On Windows, even if PHP doc says the contrary, LOCK_NB works, see

src/Symfony/Component/Filesystem/Tests/LockHandlerTest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Filesystem\Tests;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Filesystem\Exception\IOException;
16+
use Symfony\Component\Filesystem\Filesystem;
1517
use Symfony\Component\Filesystem\LockHandler;
1618

1719
class LockHandlerTest extends TestCase
@@ -40,6 +42,49 @@ public function testConstructWhenRepositoryIsNotWriteable()
4042
new LockHandler('lock', '/');
4143
}
4244

45+
public function testErrorHandlingInLockIfLockPathBecomesUnwritable()
46+
{
47+
// skip test on Windows; PHP can't easily set file as unreadable on Windows
48+
if ('\\' === DIRECTORY_SEPARATOR) {
49+
$this->markTestSkipped('This test cannot run on Windows.');
50+
}
51+
52+
$lockPath = sys_get_temp_dir().'/'.uniqid();
53+
$e = null;
54+
$wrongMessage = null;
55+
56+
try {
57+
mkdir($lockPath);
58+
59+
$lockHandler = new LockHandler('lock', $lockPath);
60+
61+
chmod($lockPath, 0444);
62+
63+
$lockHandler->lock();
64+
} catch (IOException $e) {
65+
if (false === strpos($e->getMessage(), 'Permission denied')) {
66+
$wrongMessage = $e->getMessage();
67+
} else {
68+
$this->addToAssertionCount(1);
69+
}
70+
} catch (\Exception $e) {
71+
} catch (\Throwable $e) {
72+
}
73+
74+
if (is_dir($lockPath)) {
75+
$fs = new Filesystem();
76+
$fs->remove($lockPath);
77+
}
78+
79+
if (!$e instanceof IOException) {
80+
$this->fail(sprintf('Expected IOException to be thrown, got %s instead.', get_class($e)));
81+
}
82+
83+
if (null !== $wrongMessage) {
84+
$this->fail(sprintf('Expected exception message to contain "Permission denied", got "%s" instead.', $wrongMessage));
85+
}
86+
}
87+
4388
public function testConstructSanitizeName()
4489
{
4590
$lock = new LockHandler('<?php echo "% hello word ! %" ?>');

0 commit comments

Comments
 (0)
0