PaymentApproveResource computed field exception

Created on 16 July 2024, 11 months ago

I've faced the strange behavior of computed fields when approving an order with PaymentApproveResource.
Before creating the JSON:API response object, PaymentApproveResource creates a resource object for the order with createIndividualDataFromEntity method, where I got the exception below:
InvalidArgumentException: Field 0 is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (regel 616 van /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php).

Using the stack trace I was able to discover that the problem lies in the OrderProfileItemList class, setValue() method.
It expects the $value variable to be an array containing an address key with an array of address properties.
But for some reason in this particular situation the structure of the variable is different:

0 => [
  'address' => [...]
 ]

instead of the 'address' key, it gets the 0 key and 'address' as a value and triggers an exception in profile set method

foreach ($values as $property_name => $property_value) {
  if ($property_name === 'entity') {
    continue;
  }
  $profile->set($property_name, $property_value);
}

I was not able to understand why this happen, here is a stuck trace.

#0 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(597): Drupal\Core\Entity\ContentEntityBase->getTranslatedField(0, 'x-default')
#1 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(657): Drupal\Core\Entity\ContentEntityBase->get(0)
#2 /app/web/modules/contrib/commerce_api/src/Plugin/Field/FieldType/OrderProfileItemList.php(60): Drupal\Core\Entity\ContentEntityBase->set(0, Array)
#3 /app/web/core/lib/Drupal/Core/TypedData/TypedDataManager.php(208): Drupal\commerce_api\Plugin\Field\FieldType\OrderProfileItemList->setValue(Array, false)
#4 /app/web/core/lib/Drupal/Core/Field/FieldTypePluginManager.php(83): Drupal\Core\TypedData\TypedDataManager->getPropertyInstance(Object(Drupal\Core\Entity\Plugin\DataType\EntityAdapter), 'billing_informa...', Array)
#5 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(633): Drupal\Core\Field\FieldTypePluginManager->createFieldItemList(Object(Drupal\commerce_order\Entity\Order), 'billing_informa...', Array)
#6 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(597): Drupal\Core\Entity\ContentEntityBase->getTranslatedField('billing_informa...', 'x-default')
#7 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(668): Drupal\Core\Entity\ContentEntityBase->get('billing_informa...')
#8 /app/web/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php(112): Drupal\Core\Entity\ContentEntityBase->getFields(true)
#9 /app/web/core/lib/Drupal/Core/TypedData/TypedDataInternalPropertiesHelper.php(20): Drupal\Core\Entity\Plugin\DataType\EntityAdapter->getProperties(true)
#10 /app/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(304): Drupal\Core\TypedData\TypedDataInternalPropertiesHelper::getNonInternalProperties(Object(Drupal\Core\Entity\Plugin\DataType\EntityAdapter))
#11 /app/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(243): Drupal\jsonapi\JsonApiResource\ResourceObject::extractContentEntityFields(Object(Drupal\commerce_api\ResourceType\RenamableResourceType), Object(Drupal\commerce_order\Entity\Order))
#12 /app/web/core/modules/jsonapi/src/JsonApiResource/ResourceObject.php(126): Drupal\jsonapi\JsonApiResource\ResourceObject::extractFieldsFromEntity(Object(Drupal\commerce_api\ResourceType\RenamableResourceType), Object(Drupal\commerce_order\Entity\Order))
#13 /app/web/core/modules/jsonapi/src/Access/EntityAccessChecker.php(141): Drupal\jsonapi\JsonApiResource\ResourceObject::createFromEntity(Object(Drupal\commerce_api\ResourceType\RenamableResourceType), Object(Drupal\commerce_order\Entity\Order))
#14 /app/web/modules/contrib/jsonapi_resources/src/Resource/EntityResourceBase.php(102): Drupal\jsonapi\Access\EntityAccessChecker->getAccessCheckedResourceObject(Object(Drupal\commerce_order\Entity\Order))
#15 /app/web/modules/contrib/jsonapi_resources/src/Resource/EntityResourceBase.php(74): Drupal\jsonapi_resources\Resource\EntityResourceBase->createCollectionDataFromEntities(Array, true)
#16 /app/web/modules/contrib/commerce_api/src/Resource/PaymentGateway/PaymentApproveResource.php(127): Drupal\jsonapi_resources\Resource\EntityResourceBase->createIndividualDataFromEntity(Object(Drupal\commerce_order\Entity\Order))
#17 /app/web/modules/contrib/commerce_api/src/Resource/PaymentGateway/PaymentApproveResource.php(66): Drupal\commerce_api\Resource\PaymentGateway\PaymentApproveResource->doProcess(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\commerce_order\Entity\Order))

The same behaviour applies to the PaymentInstrumentItemList.
The exception below was thrown because the structure of the $values variable is again different than expected and contains key 0 and an array value with payment_gateway_id.

if ($values['payment_gateway_id'] === NULL) {
    throw new UnprocessableEntityHttpException('You must specify a `payment_gateway_id`');
}
🐛 Bug report
Status

Active

Version

1.0

Component

Code

Created by

🇧🇾Belarus kachinsky

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024