I'm in the process of building a wrapper class for interacting with the API that makes some application specific things easier to write code for. I want to have my own Create/Update/QueryResults methods that first verify that the current session is still valid, and if necessary, refresh the session, before trying to execute the Create/Update/Query.

The difficulty I'm running into is how to properly detect an expired or otherwise invalid sessionId. In searching I found this post in which one of the answers recommends putting a try/catch around binding.getUserInfo() to detect INVALID_SESSION_ID errors, but I'm hoping someone can point me towards a better way to do it than calling binding.getUserInfo() every time a Create/Update/Query is run.



As the poster wrote:

Now to check that the sessionId is still valid, you can simply make any API call, catch the exception and deal with it as appropriate.

That means you can do something like this (using an interface):

public static SalesforceResult performAction (SalesforceAction sa) throws UnexpectedErrorFault {
    SalesforceResult sr;
    while(true) {
        try {
            return sa.execute(binding);
        } catch(UnexpectedErrorFault uef) {
            if(uef.ExceptionCode == ExceptionCode.INVALID_SESSION_ID) {
            // report any other exception to caller
            throw uef;

SalesforceAction is just an interface:

public interface SalesforceAction {
    public SalesforceResult execute(SforceClient binding) throws UnexpectedErrorFault;

You can then create objects that implement the interface for executing an action; the performAction function is boilerplate that catches a session exception and attempts a restart after refreshing the session from a source (either by password, refresh token, sso, etc).

Implementing an action can be done like this:

public class QueryAction implements SalesforceAction {
    string queryString;
    public QueryAction(String query) {
        queryString = query;
    public SalesforceResult execute(SforceClient binding) throws UnexpectedErrorFault {
        QueryResult result = binding.query(queryString);
        SalesforceResult saresult = new SalesforceResult();
        saresult.results = new SObject[] { result.records };
        return saresult;

SalesforceResult is simply an informational block that might look like this:

public class SalesforceResult {
    public bool isComplete, isSuccess;
    public SObject[][] results;
    public String[] errors;

The exact structure will depend on what your boilerplate code calls for. The original answer had these elements abstracted, because they weren't directly relevant to the question.

|improve this answer|||||
  • I'm having trouble understanding you. What is this "SalesforceResult"? I don't have anything like that. I also don't understand the SalesforceAction part at all. What is it doing and what is "SforceClient"? @sfdcfox – Jdinklage Morgoone Jan 6 '14 at 2:13
  • @JdinklageMorgoone I've updated my answer for you. – sfdcfox Jan 6 '14 at 2:20
  • 1
    The simplicity lies in the complexity; any API call will return the error, so you may as well just execute the intended call, and retry on an exception. – sfdcfox Jan 6 '14 at 2:26
  • 1
    There's only two ways about it; call a function before calling the actual function, or catch the exception as described here with a retry. Of course, without either pattern, you then have to duplicate your try-catch logic for each function you intend to call. Of course, you could just set a timer for every fifteen minutes or so and automatically re-login, but that's also not cost effective in the long run, and the session could still have expired (e.g. if it is revoked). Personally, this is how I'd do it, because it reduces the overall complexity and code duplication. – sfdcfox Jan 6 '14 at 2:49
  • 1
    @JdinklageMorgoone I just realized that I should add that the API is passive. The server may keep the session token, but the connection isn't persistent. There's no way your client app could possibly be notified that the session has expired. – sfdcfox Jan 22 '14 at 1:13

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.