Skip to content

POST on /orders fails when properties in the body are out of sequence #22998

@YurySk

Description

@YurySk
 - Summary of the issue,

POST on /orders succeeds or fails using semantically equivalent json body but different ordering of properties.
JSON data never has a guaranteed property order. Many systems use maps with undefined iteration order to form the data.

 - Information on your environment,

Magento 2.3 on Ubuntu.

 - Steps to reproduce,

Issue Swagger or Curl calls using the attached json data. One will succeed and the other woll fail even though the data is semantically equivalent and only different in the ordering of properties. See more details below.

 - Expected and actual results,

Both calls should succeed, return identical response and create the same order.

-->

Preconditions (*)

  1. Magento 2.3
  2. Ubuntu

Steps to reproduce (*)

Use Swagger or Curl to issue a POST on /orders with these json payloads. They only differ in how the properties are ordered. You will probably need to adapt the content to use a customer_id that exists on your system.

bad_json.txt
good_json.txt

  1. good.json
    POST succeeds.

  2. bad.json
    POST fails:
    {
    "message": "We can't save the address:\n%1",
    "parameters": [
    "Email has a wrong format"
    ],
    "trace": "#0 /var/www/html/magento2/vendor/magento/framework/Model/ResourceModel/Db/AbstractDb.php(410): Magento\Sales\Model\ResourceModel\Order\Address->_beforeSave(Object(Magento\Sales\Model\Order\Address))\n#1 /var/www/html/magento2/vendor/magento/framework/Model/AbstractModel.php(648): Magento\Framework\Model\ResourceModel\Db\AbstractDb->save(Object(Magento\Sales\Model\Order\Address))\n#2 /var/www/html/magento2/vendor/magento/module-sales/Model/ResourceModel/Order/Handler/Address.php(63): Magento\Framework\Model\AbstractModel->save()\n#3 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Sales\Model\ResourceModel\Order\Handler\Address->process(Object(Magento\Sales\Model\Order\Interceptor))\n#4 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Sales\Model\ResourceModel\Order\Handler\Address\Interceptor->___callParent('process', Array)\n#5 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Sales\Model\ResourceModel\Order\Handler\Address\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Sales\Model\Order\Interceptor))\n#6 /var/www/html/magento2/generated/code/Magento/Sales/Model/ResourceModel/Order/Handler/Address/Interceptor.php(39): Magento\Sales\Model\ResourceModel\Order\Handler\Address\Interceptor->___callPlugins('process', Array, Array)\n#7 /var/www/html/magento2/vendor/magento/module-sales/Model/ResourceModel/Order/Relation.php(98): Magento\Sales\Model\ResourceModel\Order\Handler\Address\Interceptor->process(Object(Magento\Sales\Model\Order\Interceptor))\n#8 /var/www/html/magento2/vendor/magento/framework/Model/ResourceModel/Db/VersionControl/RelationComposite.php(48): Magento\Sales\Model\ResourceModel\Order\Relation->processRelation(Object(Magento\Sales\Model\Order\Interceptor))\n#9 /var/www/html/magento2/vendor/magento/framework/Model/ResourceModel/Db/VersionControl/AbstractDb.php(57): Magento\Framework\Model\ResourceModel\Db\VersionControl\RelationComposite->processRelations(Object(Magento\Sales\Model\Order\Interceptor))\n#10 /var/www/html/magento2/vendor/magento/framework/Model/ResourceModel/Db/AbstractDb.php(419): Magento\Framework\Model\ResourceModel\Db\VersionControl\AbstractDb->processAfterSaves(Object(Magento\Sales\Model\Order\Interceptor))\n#11 /var/www/html/magento2/vendor/magento/module-sales/Model/ResourceModel/Order.php(178): Magento\Framework\Model\ResourceModel\Db\AbstractDb->save(Object(Magento\Sales\Model\Order\Interceptor))\n#12 /var/www/html/magento2/generated/code/Magento/Sales/Model/ResourceModel/Order/Interceptor.php(37): Magento\Sales\Model\ResourceModel\Order->save(Object(Magento\Sales\Model\Order\Interceptor))\n#13 /var/www/html/magento2/vendor/magento/module-sales/Model/OrderRepository.php(168): Magento\Sales\Model\ResourceModel\Order\Interceptor->save(Object(Magento\Sales\Model\Order\Interceptor))\n#14 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Sales\Model\OrderRepository->save(Object(Magento\Sales\Model\Order\Interceptor))\n#15 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Sales\Model\OrderRepository\Interceptor->___callParent('save', Array)\n#16 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Sales\Model\OrderRepository\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Sales\Model\Order\Interceptor))\n#17 /var/www/html/magento2/generated/code/Magento/Sales/Model/OrderRepository/Interceptor.php(78): Magento\Sales\Model\OrderRepository\Interceptor->___callPlugins('save', Array, Array)\n#18 [internal function]: Magento\Sales\Model\OrderRepository\Interceptor->save(Object(Magento\Sales\Model\Order\Interceptor))\n#19 /var/www/html/magento2/vendor/magento/module-webapi/Controller/Rest/SynchronousRequestProcessor.php(95): call_user_func_array(Array, Array)\n#20 /var/www/html/magento2/vendor/magento/module-webapi/Controller/Rest.php(188): Magento\Webapi\Controller\Rest\SynchronousRequestProcessor->process(Object(Magento\Framework\Webapi\Rest\Request\Proxy))\n#21 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Webapi\Controller\Rest->dispatch(Object(Magento\Framework\App\Request\Http))\n#22 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Webapi\Controller\Rest\Interceptor->___callParent('dispatch', Array)\n#23 /var/www/html/magento2/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Webapi\Controller\Rest\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))\n#24 /var/www/html/magento2/generated/code/Magento/Webapi/Controller/Rest/Interceptor.php(26): Magento\Webapi\Controller\Rest\Interceptor->___callPlugins('dispatch', Array, Array)\n#25 /var/www/html/magento2/vendor/magento/framework/App/Http.php(135): Magento\Webapi\Controller\Rest\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))\n#26 /var/www/html/magento2/generated/code/Magento/Framework/App/Http/Interceptor.php(24): Magento\Framework\App\Http->launch()\n#27 /var/www/html/magento2/vendor/magento/framework/App/Bootstrap.php(258): Magento\Framework\App\Http\Interceptor->launch()\n#28 /var/www/html/magento2/index.php(39): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http\Interceptor))\n#29 {main}"
    }

### Expected result (*)
Both calls should succeed, return identical response and create the same sales order.

### Actual result (*)
Success or failure depending on ordering of properties.

Metadata

Metadata

Assignees

Labels

Component: WebapiUse with concrete module component label E.g. "Component: Webapi" + "Catalog"Fixed in 2.3.xThe issue has been fixed in 2.3 release lineIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.2.xThe issue has been reproduced on latest 2.2 releaseReproduced on 2.3.xThe issue has been reproduced on latest 2.3 release

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions