Skip to content

Commit f8dff84

Browse files
authored
修复对象在 __init() 方法中初始化时抛出异常,对象还能被正常使用的问题 (#666)
* 修复对象在 __init() 方法中初始化时抛出异常,对象还能被正常使用的问题 * 修复
1 parent e462020 commit f8dff84

File tree

3 files changed

+70
-7
lines changed

3 files changed

+70
-7
lines changed

src/Bean/Container.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,32 @@ private function __newInstance(string $id, array $params, bool $allowStore)
170170

171171
if ($data['recursion'] ?? true)
172172
{
173-
// @phpstan-ignore-next-line
174-
BeanFactory::initInstance($object, $params, $originId);
175-
if ($stored && $object !== $beanObjects[$originId])
173+
if ($stored)
176174
{
177-
// 防止类 __init() 方法有协程上下文切换,导致单例被覆盖
178-
return $beanObjects[$originId];
175+
try
176+
{
177+
BeanFactory::initInstance($object, $params, $originId);
178+
if ($object !== $beanObjects[$originId])
179+
{
180+
// 防止类 __init() 方法有协程上下文切换,导致单例被覆盖
181+
return $beanObjects[$originId];
182+
}
183+
}
184+
catch (\Throwable $th)
185+
{
186+
if ($object === $beanObjects[$originId])
187+
{
188+
unset($beanObjects[$originId]);
189+
}
190+
throw $th;
191+
}
192+
}
193+
else
194+
{
195+
BeanFactory::initInstance($object, $params, $originId);
179196
}
180197
}
181198

182-
// @phpstan-ignore-next-line
183199
return $object;
184200
}
185201

@@ -272,7 +288,6 @@ public function getSingleton(string $id, ...$params)
272288
$singletonObjects[$originId] = $object;
273289
}
274290

275-
// @phpstan-ignore-next-line
276291
return $object;
277292
}
278293

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Imi\Test\Component\Bean;
6+
7+
use Imi\App;
8+
9+
class InitClass
10+
{
11+
private bool $throw;
12+
13+
public function __construct()
14+
{
15+
$this->throw = App::get('InitClass.throw');
16+
}
17+
18+
public function __init(): void
19+
{
20+
if ($this->throw)
21+
{
22+
throw new \RuntimeException('gg');
23+
}
24+
}
25+
26+
public function isThrow(): bool
27+
{
28+
return $this->throw;
29+
}
30+
}

tests/unit/Component/Tests/BeanTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Imi\Test\Component\Bean\BeanA;
1212
use Imi\Test\Component\Bean\BeanB;
1313
use Imi\Test\Component\Bean\BeanC;
14+
use Imi\Test\Component\Bean\InitClass;
1415
use Imi\Test\Component\Enum\TestEnumBean;
1516
use Imi\Test\Component\Enum\TestEnumBeanBacked;
1617
use Imi\Util\Imi;
@@ -441,6 +442,23 @@ public function testEnumBean(): void
441442
$this->assertEquals(TestEnumBeanBacked::B, $bean->getEnum3());
442443
}
443444

445+
public function testInitThrow(): void
446+
{
447+
App::set('InitClass.throw', true);
448+
try
449+
{
450+
App::getBean(InitClass::class);
451+
}
452+
catch (\Throwable $th)
453+
{
454+
$this->assertEquals('gg', $th->getMessage());
455+
}
456+
457+
App::set('InitClass.throw', false);
458+
$object = App::getBean(InitClass::class);
459+
$this->assertFalse($object->isThrow());
460+
}
461+
444462
// @phpstan-ignore-next-line
445463
private function test1(): self
446464
{

0 commit comments

Comments
 (0)