diff --git a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php
index c29b7df261d33..f2c0f96872fdd 100644
--- a/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php
+++ b/src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php
@@ -214,18 +214,24 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
if (file_exists($f['file']) && 0 <= self::$srcContext) {
if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
- $template = $f['object'] ?? unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
-
- $ellipsis = 0;
- $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
- $templateInfo = $template->getDebugInfo();
- if (isset($templateInfo[$f['line']])) {
- if (!method_exists($template, 'getSourceContext') || !file_exists($templatePath = $template->getSourceContext()->getPath())) {
- $templatePath = null;
- }
- if ($templateSrc) {
- $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
- $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
+ $template = null;
+ if (isset($f['object'])) {
+ $template = $f['object'];
+ } elseif ((new \ReflectionClass($f['class']))->isInstantiable()) {
+ $template = unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
+ }
+ if (null !== $template) {
+ $ellipsis = 0;
+ $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
+ $templateInfo = $template->getDebugInfo();
+ if (isset($templateInfo[$f['line']])) {
+ if (!method_exists($template, 'getSourceContext') || !file_exists($templatePath = $template->getSourceContext()->getPath())) {
+ $templatePath = null;
+ }
+ if ($templateSrc) {
+ $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
+ $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
+ }
}
}
}
diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php
index 50c7a8d24dca0..10cf512776096 100644
--- a/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php
+++ b/src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php
@@ -15,9 +15,12 @@
use Symfony\Component\VarDumper\Caster\Caster;
use Symfony\Component\VarDumper\Caster\ExceptionCaster;
use Symfony\Component\VarDumper\Caster\FrameStub;
+use Symfony\Component\VarDumper\Caster\TraceStub;
use Symfony\Component\VarDumper\Cloner\VarCloner;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
+use Symfony\Component\VarDumper\Tests\Fixtures\DumpClassWithErrors;
class ExceptionCasterTest extends TestCase
{
@@ -44,15 +47,15 @@ public function testDefaultSettings()
#message: "foo"
#code: 0
#file: "%sExceptionCasterTest.php"
- #line: 28
+ #line: %d
trace: {
- %s%eTests%eCaster%eExceptionCasterTest.php:28 {
+ %s%eTests%eCaster%eExceptionCasterTest.php:%d {
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest->getTestException($msg, &$ref = null)
› {
› return new \Exception(''.$msg);
› }
}
- %s%eTests%eCaster%eExceptionCasterTest.php:40 { …}
+ %s%eTests%eCaster%eExceptionCasterTest.php:%d { …}
%A
EODUMP;
@@ -66,13 +69,13 @@ public function testSeek()
$expectedDump = <<<'EODUMP'
{
- %s%eTests%eCaster%eExceptionCasterTest.php:28 {
+ %s%eTests%eCaster%eExceptionCasterTest.php:%d {
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest->getTestException($msg, &$ref = null)
› {
› return new \Exception(''.$msg);
› }
}
- %s%eTests%eCaster%eExceptionCasterTest.php:65 { …}
+ %s%eTests%eCaster%eExceptionCasterTest.php:%d { …}
%A
EODUMP;
@@ -89,15 +92,15 @@ public function testNoArgs()
#message: "1"
#code: 0
#file: "%sExceptionCasterTest.php"
- #line: 28
+ #line: %d
trace: {
- %sExceptionCasterTest.php:28 {
+ %sExceptionCasterTest.php:%d {
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest->getTestException($msg, &$ref = null)
› {
› return new \Exception(''.$msg);
› }
}
- %s%eTests%eCaster%eExceptionCasterTest.php:84 { …}
+ %s%eTests%eCaster%eExceptionCasterTest.php:%d { …}
%A
EODUMP;
@@ -114,9 +117,9 @@ public function testNoSrcContext()
#message: "1"
#code: 0
#file: "%sExceptionCasterTest.php"
- #line: 28
+ #line: %d
trace: {
- %s%eTests%eCaster%eExceptionCasterTest.php:28
+ %s%eTests%eCaster%eExceptionCasterTest.php:%d
%s%eTests%eCaster%eExceptionCasterTest.php:%d
%A
EODUMP;
@@ -124,6 +127,30 @@ public function testNoSrcContext()
$this->assertDumpMatchesFormat($expectedDump, $e);
}
+ public function testShouldReturnTraceForConcreteTwigWithError()
+ {
+ require_once \dirname(__DIR__).'/Fixtures/Twig.php';
+
+ $innerExc = (new \__TwigTemplate_VarDumperFixture_u75a09(null, __FILE__))->provideError();
+ $nestingWrapper = new \stdClass();
+ $nestingWrapper->trace = new TraceStub($innerExc->getTrace());
+
+ $expectedDump = <<<'EODUMP'
+{
+ +"trace": {
+ %sTwig.php:%d {
+ AbstractTwigTemplate->provideError()
+ › {
+ › return $this->createError();
+ › }
+ }
+ %sExceptionCasterTest.php:%d { …}
+%A
+EODUMP;
+
+ $this->assertDumpMatchesFormat($expectedDump, $nestingWrapper);
+ }
+
public function testHtmlDump()
{
if (ini_get('xdebug.file_link_format') || get_cfg_var('xdebug.file_link_format')) {
@@ -146,10 +173,10 @@ public function testHtmlDump()
#code: 0
#file: "%s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php"
- #line: 28
+ #line: %d
trace: {
%s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php:28
+Stack level %d.">%s%eVarDumper%eTests%eCaster%eExceptionCasterTest.php:%d
…%d
}
}
@@ -169,12 +196,12 @@ public function testFrameWithTwig()
$f = [
new FrameStub([
'file' => \dirname(__DIR__).'/Fixtures/Twig.php',
- 'line' => 20,
+ 'line' => 33,
'class' => '__TwigTemplate_VarDumperFixture_u75a09',
]),
new FrameStub([
'file' => \dirname(__DIR__).'/Fixtures/Twig.php',
- 'line' => 21,
+ 'line' => 34,
'class' => '__TwigTemplate_VarDumperFixture_u75a09',
'object' => new \__TwigTemplate_VarDumperFixture_u75a09(null, __FILE__),
]),
@@ -186,7 +213,7 @@ public function testFrameWithTwig()
class: "__TwigTemplate_VarDumperFixture_u75a09"
src: {
%sTwig.php:1 {
- ›
+ ›%s
› foo bar
› twig source
}
@@ -201,12 +228,11 @@ class: "__TwigTemplate_VarDumperFixture_u75a09"
%sExceptionCasterTest.php:2 {
› foo bar
› twig source
- ›
+ ›%s
}
}
}
]
-
EODUMP;
$this->assertDumpMatchesFormat($expectedDump, $f);
@@ -221,7 +247,7 @@ public function testExcludeVerbosity()
#message: "foo"
#code: 0
#file: "%sExceptionCasterTest.php"
- #line: 28
+ #line: %d
}
EODUMP;
diff --git a/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php b/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php
index 8b84d820fcf7c..5d1a73d424b4b 100644
--- a/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php
+++ b/src/Symfony/Component/VarDumper/Tests/Fixtures/Twig.php
@@ -1,7 +1,20 @@
createError();
+ }
+}
+
/* foo.twig */
-class __TwigTemplate_VarDumperFixture_u75a09 extends Twig\Template
+class __TwigTemplate_VarDumperFixture_u75a09 extends AbstractTwigTemplate
{
private $path;
@@ -28,7 +41,7 @@ public function getTemplateName()
public function getDebugInfo()
{
- return [20 => 1, 21 => 2];
+ return [33 => 1, 34 => 2];
}
public function getSourceContext()