Salesforce wsc: ConnectionException should have been Fault

This is the first article where I discuss details or issues using wsc (JAVA) on an Oracle WebLogic platform to integrate Customer Legacy systems with Salesforce CRM.

In some environments (specifically the WLS 10.3.5 used as production environment at my current Customer) the wsc infrastructure throws a ConnectionException (com.sforce.ws.ConnectionException: Unexpected element) in situations where it should actually return a Fault (com.sforce.soap.enterprise.fault.ApiFault).

I have tried to mock a similar environment in order to demonstrate the problem to no avail.

But, I have discovered why the problem arises – it has to do with the infrastructure related to the Transport.isSuccessful().

The exception is similar to the one below:

com.sforce.ws.ConnectionException: Unexpected element. Parser was expecting element 'urn:enterprise.soap.sforce.com:upsertResponse' but found 'http://schemas.xmlsoap.org/soap/envelope/:Fault'
	at com.sforce.ws.bind.TypeMapper.verifyTag(TypeMapper.java:386)
	at com.sforce.ws.transport.SoapConnection.bind(SoapConnection.java:166)
	at com.sforce.ws.transport.SoapConnection.receive(SoapConnection.java:147)
	at com.sforce.ws.transport.SoapConnection.send(SoapConnection.java:98)
	at com.sforce.soap.enterprise.EnterpriseConnection.upsert(EnterpriseConnection.java:856)
	at ...

The problem is that the code in SoapConnection (com.sforce.ws.transport.SoapConnection:146) gets confused by the Transport object returning true from the isSuccessful() method. Then it goes on to create the expected response type in the bind() method, which fails because it does not expect a Fault…

My first solution (described in sfdc-wsc: Issue 64) was to hack the bind() method to handle unexpected Faults and not just the expected return type…

That hack was not optimum as the real issue was not discovered – basically because of lack of an environment where I could debug the issue.

After a while it became obvious that the real problem was that the Transport object returned “success” even if the infrastructure returned Fault. This again is related to the jre specific implementations of the HttpURLConnection

The JavaDoc is not clear on this, but some implementations throw an IOException on getInputStream() and some does not, when the server returns an error. I.e the code below is not stable across different environments/implementations:

191
192
193
194
195
196
197
198
199
200
201
202
203
204
public InputStream getContent() throws IOException {
        InputStream in;
 
        try {
            successful = true;
            in = connection.getInputStream();
        } catch (IOException e) {
            successful = false;
            in = connection.getErrorStream();
            if (in == null) {
                throw e;
            }
        }
...

Basically the successful flag is left as true even if the service returns an error.

Changing the above lines of code of the getContent() method in the JdkHttpTransport class (com.sforce.ws.transport.JdkHttpTransport:191) seems to make the code robust, as it does not set the flag based on a possible exception, but from determining the HTTP response code from the server:

191
192
193
194
195
196
197
198
199
200
201
202
203
204
public InputStream getContent() throws IOException {
        InputStream in;
 
        try {
            in = connection.getInputStream();
        } catch (IOException e) {
            in = connection.getErrorStream();
            if (in == null) {
                throw e;
            }
        }
 
        this.successful = connection.getResponseCode() < 400;
...

This solution has been added in the comments to the issue and we can hope it gets included in a future version of the wsc tool 🙂

About Jesper Udby

I'm a freelance computer Geek living in Denmark with my wife and 3 kids. I've done professional software development since 1994 and JAVA development since 1998.
This entry was posted in Java, Salesforce and tagged , , , , , . Bookmark the permalink.

2 Responses to Salesforce wsc: ConnectionException should have been Fault

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.