@@ -74,7 +74,7 @@ protected function processValue($value, $isRoot = false)
74
74
throw $ e ;
75
75
}
76
76
77
- $ this ->container ->getDefinition ($ this ->currentId )->addError ($ e ->getMessage ());
77
+ $ this ->container ->getDefinition ($ this ->currentId )->addError ($ e ->getMessageCallback () ?? $ e -> getMessage ());
78
78
79
79
return parent ::processValue ($ value , $ isRoot );
80
80
}
@@ -86,16 +86,15 @@ private function doProcessValue($value, $isRoot = false)
86
86
if ($ ref = $ this ->getAutowiredReference ($ value )) {
87
87
return $ ref ;
88
88
}
89
- $ message = $ this ->createTypeNotFoundMessage ($ value , 'it ' );
90
-
91
89
if (ContainerBuilder::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $ value ->getInvalidBehavior ()) {
90
+ $ message = $ this ->createTypeNotFoundMessageCallback ($ value , 'it ' );
91
+
92
92
// since the error message varies by referenced id and $this->currentId, so should the id of the dummy errored definition
93
93
$ this ->container ->register ($ id = sprintf ('.errored.%s.%s ' , $ this ->currentId , (string ) $ value ), $ value ->getType ())
94
94
->addError ($ message );
95
95
96
96
return new TypedReference ($ id , $ value ->getType (), $ value ->getInvalidBehavior (), $ value ->getName ());
97
97
}
98
- $ this ->container ->log ($ this , $ message );
99
98
}
100
99
$ value = parent ::processValue ($ value , $ isRoot );
101
100
@@ -222,14 +221,13 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
222
221
223
222
$ getValue = function () use ($ type , $ parameter , $ class , $ method ) {
224
223
if (!$ value = $ this ->getAutowiredReference ($ ref = new TypedReference ($ type , $ type , ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE , $ parameter ->name ))) {
225
- $ failureMessage = $ this ->createTypeNotFoundMessage ($ ref , sprintf ('argument "$%s" of method "%s()" ' , $ parameter ->name , $ class !== $ this ->currentId ? $ class .':: ' .$ method : $ method ));
224
+ $ failureMessage = $ this ->createTypeNotFoundMessageCallback ($ ref , sprintf ('argument "$%s" of method "%s()" ' , $ parameter ->name , $ class !== $ this ->currentId ? $ class .':: ' .$ method : $ method ));
226
225
227
226
if ($ parameter ->isDefaultValueAvailable ()) {
228
227
$ value = $ parameter ->getDefaultValue ();
229
228
} elseif (!$ parameter ->allowsNull ()) {
230
229
throw new AutowiringFailedException ($ this ->currentId , $ failureMessage );
231
230
}
232
- $ this ->container ->log ($ this , $ failureMessage );
233
231
}
234
232
235
233
return $ value ;
@@ -307,27 +305,27 @@ private function getAutowiredReference(TypedReference $reference)
307
305
/**
308
306
* Populates the list of available types.
309
307
*/
310
- private function populateAvailableTypes ()
308
+ private function populateAvailableTypes (ContainerBuilder $ container )
311
309
{
312
310
$ this ->types = array ();
313
311
$ this ->ambiguousServiceTypes = array ();
314
312
315
- foreach ($ this -> container ->getDefinitions () as $ id => $ definition ) {
316
- $ this ->populateAvailableType ($ id , $ definition );
313
+ foreach ($ container ->getDefinitions () as $ id => $ definition ) {
314
+ $ this ->populateAvailableType ($ container , $ id , $ definition );
317
315
}
318
316
}
319
317
320
318
/**
321
319
* Populates the list of available types for a given definition.
322
320
*/
323
- private function populateAvailableType (string $ id , Definition $ definition )
321
+ private function populateAvailableType (ContainerBuilder $ container , string $ id , Definition $ definition )
324
322
{
325
323
// Never use abstract services
326
324
if ($ definition ->isAbstract ()) {
327
325
return ;
328
326
}
329
327
330
- if ('' === $ id || '. ' === $ id [0 ] || $ definition ->isDeprecated () || !$ reflectionClass = $ this -> container ->getReflectionClass ($ definition ->getClass (), false )) {
328
+ if ('' === $ id || '. ' === $ id [0 ] || $ definition ->isDeprecated () || !$ reflectionClass = $ container ->getReflectionClass ($ definition ->getClass (), false )) {
331
329
return ;
332
330
}
333
331
@@ -367,19 +365,21 @@ private function set(string $type, string $id)
367
365
$ this ->ambiguousServiceTypes [$ type ][] = $ id ;
368
366
}
369
367
370
- private function createTypeNotFoundMessage (TypedReference $ reference , $ label )
368
+ private function createTypeNotFoundMessageCallback (TypedReference $ reference , $ label )
371
369
{
372
- $ trackResources = $ this ->container ->isTrackingResources ( );
373
- $ this ->container ->setResourceTracking ( false );
374
- try {
375
- if ( $ r = $ this -> container ->getReflectionClass ( $ type = $ reference -> getType (), false )) {
376
- $ alternatives = $ this -> createTypeAlternatives ( $ reference );
377
- }
378
- } finally {
379
- $ this -> container -> setResourceTracking ( $ trackResources ) ;
380
- }
370
+ $ container = new ContainerBuilder ( $ this ->container ->getParameterBag () );
371
+ $ container -> setAliases ( $ this ->container ->getAliases () );
372
+ $ container -> setDefinitions ( $ this -> container -> getDefinitions ());
373
+ $ container ->setResourceTracking ( false );
374
+
375
+ return function () use ( $ container , $ reference , $ label ) {
376
+ return $ this -> createTypeNotFoundMessage ( $ container , $ reference , $ label );
377
+ } ;
378
+ }
381
379
382
- if (!$ r ) {
380
+ private function createTypeNotFoundMessage (ContainerBuilder $ container , TypedReference $ reference , $ label )
381
+ {
382
+ if (!$ r = $ container ->getReflectionClass ($ type = $ reference ->getType (), false )) {
383
383
// either $type does not exist or a parent class does not exist
384
384
try {
385
385
$ resource = new ClassExistenceResource ($ type , false );
@@ -392,7 +392,8 @@ private function createTypeNotFoundMessage(TypedReference $reference, $label)
392
392
393
393
$ message = sprintf ('has type "%s" but this class %s. ' , $ type , $ parentMsg ? sprintf ('is missing a parent class (%s) ' , $ parentMsg ) : 'was not found ' );
394
394
} else {
395
- $ message = $ this ->container ->has ($ type ) ? 'this service is abstract ' : 'no such service exists ' ;
395
+ $ alternatives = $ this ->createTypeAlternatives ($ container , $ reference );
396
+ $ message = $ container ->has ($ type ) ? 'this service is abstract ' : 'no such service exists ' ;
396
397
$ message = sprintf ('references %s "%s" but %s.%s ' , $ r ->isInterface () ? 'interface ' : 'class ' , $ type , $ message , $ alternatives );
397
398
398
399
if ($ r ->isInterface () && !$ alternatives ) {
@@ -410,18 +411,18 @@ private function createTypeNotFoundMessage(TypedReference $reference, $label)
410
411
return $ message ;
411
412
}
412
413
413
- private function createTypeAlternatives (TypedReference $ reference )
414
+ private function createTypeAlternatives (ContainerBuilder $ container , TypedReference $ reference )
414
415
{
415
416
// try suggesting available aliases first
416
- if ($ message = $ this ->getAliasesSuggestionForType ($ type = $ reference ->getType ())) {
417
+ if ($ message = $ this ->getAliasesSuggestionForType ($ container , $ type = $ reference ->getType ())) {
417
418
return ' ' .$ message ;
418
419
}
419
420
if (null === $ this ->ambiguousServiceTypes ) {
420
- $ this ->populateAvailableTypes ();
421
+ $ this ->populateAvailableTypes ($ container );
421
422
}
422
423
423
- $ servicesAndAliases = $ this -> container ->getServiceIds ();
424
- if (!$ this -> container ->has ($ type ) && false !== $ key = array_search (strtolower ($ type ), array_map ('strtolower ' , $ servicesAndAliases ))) {
424
+ $ servicesAndAliases = $ container ->getServiceIds ();
425
+ if (!$ container ->has ($ type ) && false !== $ key = array_search (strtolower ($ type ), array_map ('strtolower ' , $ servicesAndAliases ))) {
425
426
return sprintf (' Did you mean "%s"? ' , $ servicesAndAliases [$ key ]);
426
427
} elseif (isset ($ this ->ambiguousServiceTypes [$ type ])) {
427
428
$ message = sprintf ('one of these existing services: "%s" ' , implode ('", " ' , $ this ->ambiguousServiceTypes [$ type ]));
@@ -434,11 +435,11 @@ private function createTypeAlternatives(TypedReference $reference)
434
435
return sprintf (' You should maybe alias this %s to %s. ' , class_exists ($ type , false ) ? 'class ' : 'interface ' , $ message );
435
436
}
436
437
437
- private function getAliasesSuggestionForType ($ type , $ extraContext = null )
438
+ private function getAliasesSuggestionForType (ContainerBuilder $ container , $ type , $ extraContext = null )
438
439
{
439
440
$ aliases = array ();
440
441
foreach (class_parents ($ type ) + class_implements ($ type ) as $ parent ) {
441
- if ($ this -> container ->has ($ parent ) && !$ this -> container ->findDefinition ($ parent )->isAbstract ()) {
442
+ if ($ container ->has ($ parent ) && !$ container ->findDefinition ($ parent )->isAbstract ()) {
442
443
$ aliases [] = $ parent ;
443
444
}
444
445
}