14
14
use Symfony \Component \HttpFoundation \Exception \RequestExceptionInterface ;
15
15
use Symfony \Component \HttpFoundation \Response ;
16
16
use Symfony \Component \HttpKernel \Exception \HttpExceptionInterface ;
17
+ use Symfony \Component \VarDumper \Caster \Caster ;
18
+ use Symfony \Component \VarDumper \Cloner \Data ;
19
+ use Symfony \Component \VarDumper \Cloner \Stub ;
20
+ use Symfony \Component \VarDumper \Cloner \VarCloner ;
17
21
18
22
/**
19
23
* FlattenException wraps a PHP Error or Exception to be able to serialize it.
@@ -36,7 +40,7 @@ class FlattenException
36
40
private string $ file ;
37
41
private int $ line ;
38
42
private ?string $ asString = null ;
39
- private array $ properties = [] ;
43
+ private Data $ dataRepresentation ;
40
44
41
45
public static function create (\Exception $ exception , int $ statusCode = null , array $ headers = []): static
42
46
{
@@ -78,14 +82,34 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod
78
82
$ e ->setPrevious (static ::createFromThrowable ($ previous ));
79
83
}
80
84
81
- if ((new \ReflectionClass ($ exception ::class))->isUserDefined ()) {
82
- $ getProperties = \Closure::bind (fn (\Throwable $ e ) => get_object_vars ($ e ), null , $ exception ::class);
83
- $ properties = $ getProperties ($ exception );
84
- unset($ properties ['message ' ], $ properties ['code ' ], $ properties ['file ' ], $ properties ['line ' ]);
85
- $ e ->properties = $ properties ;
85
+ return $ e ;
86
+ }
87
+
88
+ public static function createWithDataRepresentation (\Throwable $ throwable , int $ statusCode = null , array $ headers = [], VarCloner $ cloner = null ): static
89
+ {
90
+ $ e = static ::createFromThrowable ($ throwable , $ statusCode , $ headers );
91
+
92
+ static $ defaultCloner ;
93
+
94
+ if (!$ cloner ??= $ defaultCloner ) {
95
+ $ cloner = $ defaultCloner = new VarCloner ();
96
+ $ cloner ->addCasters ([
97
+ \Throwable::class => function (\Throwable $ e , array $ a , Stub $ s , bool $ isNested ): array {
98
+ if (!$ isNested ) {
99
+ unset($ a [Caster::PREFIX_PROTECTED .'message ' ]);
100
+ unset($ a [Caster::PREFIX_PROTECTED .'code ' ]);
101
+ unset($ a [Caster::PREFIX_PROTECTED .'file ' ]);
102
+ unset($ a [Caster::PREFIX_PROTECTED .'line ' ]);
103
+ unset($ a ["\0Error \0trace " ], $ a ["\0Exception \0trace " ]);
104
+ unset($ a ["\0Error \0previous " ], $ a ["\0Exception \0previous " ]);
105
+ }
106
+
107
+ return $ a ;
108
+ },
109
+ ]);
86
110
}
87
111
88
- return $ e ;
112
+ return $ e-> setDataRepresentation ( $ cloner -> cloneVar ( $ throwable )) ;
89
113
}
90
114
91
115
public function toArray (): array
@@ -96,7 +120,7 @@ public function toArray(): array
96
120
'message ' => $ exception ->getMessage (),
97
121
'class ' => $ exception ->getClass (),
98
122
'trace ' => $ exception ->getTrace (),
99
- 'properties ' => $ exception ->getProperties (),
123
+ 'data ' => $ exception ->getDataRepresentation (),
100
124
];
101
125
}
102
126
@@ -230,11 +254,6 @@ public function setCode(int|string $code): static
230
254
return $ this ;
231
255
}
232
256
233
- public function getProperties (): array
234
- {
235
- return $ this ->properties ;
236
- }
237
-
238
257
public function getPrevious (): ?self
239
258
{
240
259
return $ this ->previous ;
@@ -319,6 +338,21 @@ public function setTrace(array $trace, ?string $file, ?int $line): static
319
338
return $ this ;
320
339
}
321
340
341
+ public function getDataRepresentation (): ?Data
342
+ {
343
+ return $ this ->dataRepresentation ?? null ;
344
+ }
345
+
346
+ /**
347
+ * @return $this
348
+ */
349
+ public function setDataRepresentation (Data $ data ): static
350
+ {
351
+ $ this ->dataRepresentation = $ data ;
352
+
353
+ return $ this ;
354
+ }
355
+
322
356
private function flattenArgs (array $ args , int $ level = 0 , int &$ count = 0 ): array
323
357
{
324
358
$ result = [];
0 commit comments