6

I am trying to create a list view on a custom object from nodejs server. I have constructed a the SOAP(XML) body like I had done here, but I keep getting the Premature End of File error, which doesn't make sense as the XML is properly parsed and the list get created if I do it from salesforce's developer console.

I got a few link, here and here, on this error but I was unable to figure out the solution for this.

nodeServer.js:

    var https = require('https');
var userSessionId = 'sessionId';
var b = '<?xml version="1.0" encoding="UTF-8"?>';
b += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
    b += '<soapenv:Header>';
        b += '<ns1:SessionHeader soapenv:mustUnderstand="0" xmlns:ns1="http://soap.sforce.com/2006/04/metadata">';
        b += '<ns1:sessionId>'+userSessionId+'</ns1:sessionId>';
        b += '</ns1:SessionHeader>';
    b += '</soapenv:Header>';
    b += '<soapenv:Body>';
        b += '<create xmlns="http://soap.sforce.com/2006/04/metadata">';
            b += '<metadata xsi:type="ns2:ListView" xmlns:ns2="http://soap.sforce.com/2006/04/metadata">';
                //This is the API name of the list view
                b += '<fullName>Car_Object__c.Merc_View</fullName>';
                b += '<booleanFilter>1</booleanFilter>';
                //Columns you want to display
                b += '<columns>NAME</columns>';
                b += '<columns>CREATED_DATE</columns>';
                //Filterscope should be set to Everything for every one to be able to access this List view
                b += '<filterScope>Everything</filterScope>';
                // Enter the filter that you want to set
                b += '<filters>';
                    b += '<field>NAME</field>';
                    b += '<operation>equals</operation>';
                    b += '<value>Mercedes</value>';
                b += '</filters>';
                b += '<label>Mercedes View</label>';
            b += '</metadata>';
        b += '</create>';
    b += '</soapenv:Body>';
b += '</soapenv:Envelope>';

callMyfunction();

function callMyfunction(){
var options = {
    host : "myhost",
    path : '/services/Soap/m/29.0',
    method: "POST",
    headers : {'Authorization':'Bearer '+userSessionId,
                'Content-Type': 'text/xml',
                'SOAPAction':'Create',
            },
    data : b
    };
    console.log('the '+ JSON.stringify(options));
    var req = https.request(options, function(res){
        res.setEncoding('utf8');
        var output='';
            res.on('data',function(chunk){
                output +=chunk;
                console.log('Print the chunk--> \n'+ chunk);
            });
            res.on('end',function(){
                console.log('Final Data is--> \n'+ output);         
            });
    });
    req.on('error',function(e){
        console.log('the erro msg'+ e);
    });
    req.end();  
}

Result:

Print the chunk-->
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:Client</faultcode>
            <faultstring>Premature end of file.</faultstring>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>

Final Data is-->
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:Client</faultcode>
            <faultstring>Premature end of file.</faultstring>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>
7
+50

Firstly, thanks for prompting me to finally give NodeJS a go! I'm pleased to say I've also been able to identify your problem. Looking through the docs here, i noticed that 'data' was not a valid member of the options structure. What you have to do is utilise the write method on the http.ClientRequest object returned from the https.request method, before calling the end method.

req.write(b);
req.end();  

Without this, no data is actually sent, and thus Salesforce claims there is is a premature end to the request, which i would agree is perhaps not the most clear way of say, no data sent.

  • 1
    Thank you very much Andrew for help! I think I would never have figured this out my self :) – Sam Mar 10 '14 at 11:07
  • 1
    Your very welcome, i must say it was pretty straight forward to get NodeJS up and running on my Mac and try this out, so thank you for prompting me to have a play with this! Been on my list for a little while. ;-) – Andrew Fawcett Mar 10 '14 at 11:50

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.