When calling the Magento2 SOAP API to create a new product, I get a generic error message saying 'Invalid product data: %1'. I was hoping that the Magento2 API would throw better exceptions than Magento1 but unfortunately they seem to be just as awful and generic.

Is there any way to get the actual exception somewhere? Or do we just trial and error?


In general

In addition to "message" element, response has "parameters" element, which contains data for placeholders in the message. This approach allows customization of actual message shown to the end user, while still allows usage of parameters in the custom message. For example, if you do not have enough permissions to access some resource you get:

    "message": "Consumer is not authorized to access %resources",
        "resources": "Magento_Catalog::products"

It is also possible to get full exception stack trace by enabling developer mode in Magento (by uncommenting SetEnv MAGE_MODE developer in the root .htaccess).

Described behavior is uniform in REST and SOAP.

Issue in SOAP

Described issue in SOAP (internal issue MAGETWO-46088) is reproducible in case when exception in the underlying service is thrown in the way:

throw new \Magento\Framework\Exception\CouldNotSaveException(
    __('Invalid product data: %1', implode(',', $validationResult))

It would be rendered correctly if parameters were passed as an associative array like:

throw new \Magento\Framework\Exception\CouldNotSaveException(
    __('Invalid product data: %message', ['message' => implode(',', $validationResult)])

Workaround (until issue is fixed in core)

To get parameters rendered properly you have to modify core code (not possible via plugin because this SOAP fault objects are instantiated using new).

In this method \Magento\Webapi\Model\Soap\Fault::_getParametersXml replace

if (is_string($parameterName) && (is_string($parameterValue) || is_numeric($parameterValue))) {

with this

if ((is_string($parameterName) || is_numeric($parameterName))
    && (is_string($parameterValue) || is_numeric($parameterValue))
) {
    if (is_numeric($parameterName)) {
| improve this answer | |
  • Thanks, enabling the developer mode does mean a more detailed exception is returned. But in this case it doesn't really include any useful information. At least now I know how to get the whole trace. – Erik Nov 26 '15 at 13:15
  • I didn't want to suggest changes in core, but this is the only way to fix it. See update. – Alex Paliarush Nov 26 '15 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.