pythondjangosuds

Suds throwing exception on "type not found"


We are using SUDS v1.1.1 and recently starting getting a "Type not found" exception as the response to a request contains a field not in the wsdl. I tried initializing the client as follows but the exception is still occurring:

client = Client(spec_path, faults=False)
client.set_options(allowUnknownMessageParts=True, extraArgumentErrors=False)

Is there any other way to get suds to ignore the unknown field without throwing an exception please?

Updates

Error Generated by Library

Type not found: ‘accountNumber'

XML Response

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getTransactionResponse xmlns:ns2="http://soap.api.controller.web.payjar.com/"><return><basket><amountInCents>500</amountInCents><currencyCode>ZAR</currencyCode><description>ABC Retailer</description></basket><displayMessage>Successful</displayMessage><merchantReference>114ff7d7-3a6d-44e1-bff7-dfjkheuiier789</merchantReference><payUReference>dfskjskjdfhjkksk</payUReference><paymentMethodsUsed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:capitecPay"><accountNumber>12347383643</accountNumber><amountInCents>500</amountInCents><beneficiaryStatementDescription>CAPITEC1748237482597</beneficiaryStatementDescription><transactionId>a8f64064-39f2-11f0-9fde-ejnsduinsiuefnf</transactionId></paymentMethodsUsed><resultCode>00</resultCode><resultMessage>Successful</resultMessage><successful>true</successful><transactionState>SUCCESSFUL</transactionState><transactionType>PAYMENT</transactionType></return></ns2:getTransactionResponse></soap:Body></soap:Envelope>

wsdl

Can be downloaded here.


Solution

  • Could you provide more details (code) about your issue? I was also wondering if you've tried using a custom plugin to bypass the problem, something like:

    
    class IgnoreUnknownFieldsPlugin(MessagePlugin):
        def unmarshalled(self, context):
            # Remove unknown elements before SUDS processes them
            if hasattr(context.reply, 'children'):
                known_elements = [el for el in context.reply.children if el.name in context.reply.__metadata__.sxtype.rawchildren]
                context.reply.children = known_elements
    
    client = Client(spec_path, plugins=[IgnoreUnknownFieldsPlugin()], faults=False)
    

    UPDATE:

    The issue occurs because the response contains a payment method type (capitecPay) with an accountNumber field that isn't defined in the WSDL schema, so we will update the plugin to handle paymentMethodsUsed array with unknown types.

    
    class PayUResponseFixPlugin(MessagePlugin):
        def unmarshalled(self, context):
            # Handle paymentMethodsUsed array with unknown types
            if hasattr(context.reply, 'paymentMethodsUsed'):
                for payment_method in context.reply.paymentMethodsUsed:
                    # Skip validation for unknown payment method types
                    if not hasattr(payment_method, '__metadata__'):
                        # Copy metadata from parent to make it valid
                        payment_method.__metadata__ = context.reply.__metadata__
            
            # Original handling for other unknown elements
            if hasattr(context.reply, 'children'):
                known_elements = [el for el in context.reply.children 
                                if el.name in context.reply.__metadata__.sxtype.rawchildren]
                context.reply.children = known_elements
                
            return context.reply
    
    client = Client(
        spec_path,
        plugins=[PayUResponseFixPlugin()],
        faults=False,
        allowUnknownMessageParts=True
    )`