Kathara
Kathara

Reputation: 1290

TYPO3 v10.4.21 custom FormFinisher: Simultaneous execution resulting in exception

We've created a custom form finisher with the following constructor:

/**
* @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager $persistenceManager
*/
protected $persistenceManager = null;

/**
* @var \[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository $articleRepository
*/
protected $articleRepository = null;

public function __construct() {
    parent::__construct();
    $this->persistenceManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
    $this->articleRepository = GeneralUtility::makeInstance(\[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository::class);
}

When the form is executed almost simultaneously (delay of 1-5 seconds tested) one of the form submitters gets the error:

Too few arguments to function TYPO3\CMS\Extbase\Persistence\Repository::__construct(), 0 passed in [path_to_docroot]/httpdocs/typo3/sysext/core/Classes/Utility/GeneralUtility.php on line 3477 and exactly 1 expected

This happens when it's trying to create the instance of the ArticleRepository:


1:

at TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository') in [path_to_docroot]/httpdocs/typo3conf/ext/[ext_name]/Classes/Domain/Finishers/ImageGalleryFinisher.php line 31

28  public function __construct() {
29      parent::__construct();
30      $this->persistenceManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager::class);
31      $this->articleRepository = GeneralUtility::makeInstance(\[NAMESPACE]\[ExtName]\Domain\Repository\ArticleRepository::class);
32  }

2:

at TYPO3\CMS\Extbase\Persistence\Repository->__construct() in [path_to_docroot]/httpdocs/typo3/sysext/core/Classes/Utility/GeneralUtility.php line 3477

3473         return self::$container->get($className);
3474     }
3475 
3476     // Create new instance and call constructor with parameters
3477     $instance = new $finalClassName(...$constructorArguments);
3478     // Register new singleton instance, but only if it is not a known PSR-11 container service
3479     if ($instance instanceof SingletonInterface && !(self::$container !== null && self::$container->has($className))) {
3480         self::$singletonInstances[$finalClassName] = $instance;
3481     }

3 (where the error occurs):

in [path_to_docroot]/httpdocs/typo3/sysext/extbase/Classes/Persistence/Repository.php line 71

67   * Constructs a new Repository
68   *
69   * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
70   */
71  public function __construct(ObjectManagerInterface $objectManager) 
72  {
73      $this->objectManager = $objectManager;
74      $this->objectType = ClassNamingUtility::translateRepositoryNameToModelName($this->getRepositoryClassName());
75  }

The other submission is executed without problems. We've tested this on a staging environment. My colleague couldn't recreate the same error locally by executing 2 forms simultaneously (although he might have a faster execution than the staging environment).

I recon that the problem is the simultaneous execution of the finisher. But why? Can this be prevented? Is there a possibility to relay the ObjectManagerInterface to this constructor?

Or can anyone see another flaw? Or is this a bug somewhere in the core?

I couldn't find anything... Any help or pointers would be highly appreciated, thanks.

Upvotes: 0

Views: 269

Answers (1)

Kathara
Kathara

Reputation: 1290

After trying many different things I eventually found the solution.

Using the inject annotation:

/**
* @var PersistenceManager $persistenceManager
* @\TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $persistenceManager = null;

/**
* @var ArticleRepository $articleRepository
* @\TYPO3\CMS\Extbase\Annotation\Inject
*/
protected $articleRepository = null;

The constructor can then be deleted and it works with simultaneous execution. Cheers!

Upvotes: 0

Related Questions