Skip to content

Commit 8e87760

Browse files
sebastianbergmannSchranktheseerstaabmTesla91
committed
Closes #5844
Co-authored-by: Sebastian Bergmann <[email protected]> Co-authored-by: Fabian Blechschmidt <[email protected]> Co-authored-by: Arne Blankerts <[email protected]> Co-authored-by: Markus Staab <[email protected]> Co-authored-by: Nicola Pilcher <[email protected]> Co-authored-by: Andreas Möller <[email protected]> Co-authored-by: Sebastian Heuer <[email protected]>
1 parent 59f3b51 commit 8e87760

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

ChangeLog-11.4.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ All notable changes of the PHPUnit 11.4 release series are documented in this fi
1010

1111
### Fixed
1212

13+
* [#5844](https://github.com/sebastianbergmann/phpunit/issues/5844): Error handlers that are not callable outside the scope they were registered in are not handled correctly
1314
* [#5982](https://github.com/sebastianbergmann/phpunit/pull/5982): Typo in exception message
1415

1516
## [11.4.1] - 2024-10-08

src/Framework/TestCase.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,7 +1974,7 @@ private function restoreGlobalErrorExceptionHandlers(): void
19741974
*/
19751975
private function getActiveErrorHandlers(): array
19761976
{
1977-
$res = [];
1977+
$activeErrorHandlers = [];
19781978

19791979
while (true) {
19801980
$previousHandler = set_error_handler(static fn () => false);
@@ -1985,18 +1985,37 @@ private function getActiveErrorHandlers(): array
19851985
break;
19861986
}
19871987

1988-
$res[] = $previousHandler;
1988+
$activeErrorHandlers[] = $previousHandler;
19891989

19901990
restore_error_handler();
19911991
}
19921992

1993-
$res = array_reverse($res);
1993+
$activeErrorHandlers = array_reverse($activeErrorHandlers);
1994+
$invalidErrorHandlerStack = false;
1995+
1996+
foreach ($activeErrorHandlers as $handler) {
1997+
if (!is_callable($handler)) {
1998+
$invalidErrorHandlerStack = true;
1999+
2000+
continue;
2001+
}
19942002

1995-
foreach ($res as $handler) {
19962003
set_error_handler($handler);
19972004
}
19982005

1999-
return $res;
2006+
/** @phpstan-ignore if.alwaysFalse */
2007+
if ($invalidErrorHandlerStack) {
2008+
$message = 'At least one error handler is not callable outside the scope it was registered in';
2009+
2010+
Event\Facade::emitter()->testConsideredRisky(
2011+
$this->valueObjectForEvents(),
2012+
$message,
2013+
);
2014+
2015+
$this->status = TestStatus::risky($message);
2016+
}
2017+
2018+
return $activeErrorHandlers;
20002019
}
20012020

20022021
/**

tests/end-to-end/regression/5844.phpt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
https://github.com/sebastianbergmann/phpunit/issues/5844
3+
--FILE--
4+
<?php declare(strict_types=1);
5+
$_SERVER['argv'][] = '--do-not-cache-result';
6+
$_SERVER['argv'][] = '--no-configuration';
7+
$_SERVER['argv'][] = '--debug';
8+
$_SERVER['argv'][] = '--bootstrap';
9+
$_SERVER['argv'][] = __DIR__ . '/5844/bootstrap.php';
10+
$_SERVER['argv'][] = __DIR__ . '/5844/Issue5844Test.php';
11+
12+
require_once __DIR__ . '/../../bootstrap.php';
13+
14+
(new PHPUnit\TextUI\Application)->run($_SERVER['argv']);
15+
--EXPECTF--
16+
PHPUnit Started (PHPUnit %s using %s)
17+
Test Runner Configured
18+
Bootstrap Finished (%s5844%sbootstrap.php)
19+
Event Facade Sealed
20+
Test Suite Loaded (1 test)
21+
Test Runner Started
22+
Test Suite Sorted
23+
Test Runner Execution Started (1 test)
24+
Test Suite Started (PHPUnit\TestFixture\Issue5844\Issue5844Test, 1 test)
25+
Test Preparation Started (PHPUnit\TestFixture\Issue5844\Issue5844Test::testOne)
26+
Test Considered Risky (PHPUnit\TestFixture\Issue5844\Issue5844Test::testOne)
27+
At least one error handler is not callable outside the scope it was registered in
28+
Test Prepared (PHPUnit\TestFixture\Issue5844\Issue5844Test::testOne)
29+
Test Passed (PHPUnit\TestFixture\Issue5844\Issue5844Test::testOne)
30+
Test Finished (PHPUnit\TestFixture\Issue5844\Issue5844Test::testOne)
31+
Test Suite Finished (PHPUnit\TestFixture\Issue5844\Issue5844Test, 1 test)
32+
Test Runner Execution Finished
33+
Test Runner Finished
34+
PHPUnit Finished (Shell Exit Code: 0)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\Issue5844;
11+
12+
use PHPUnit\Framework\TestCase;
13+
14+
final class Issue5844Test extends TestCase
15+
{
16+
public function testOne(): void
17+
{
18+
$this->assertTrue(true);
19+
}
20+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php declare(strict_types=1);
2+
/*
3+
* This file is part of PHPUnit.
4+
*
5+
* (c) Sebastian Bergmann <[email protected]>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
namespace PHPUnit\TestFixture\Issue5844;
11+
12+
use function set_error_handler;
13+
14+
final class CustomErrorHandler
15+
{
16+
public function __construct()
17+
{
18+
set_error_handler([$this, 'handleError']);
19+
}
20+
21+
private function handleError(): void
22+
{
23+
}
24+
}
25+
26+
new CustomErrorHandler;

0 commit comments

Comments
 (0)