5

Assume we have an Apex class myClass.cls and we use it on several different Orgs. While the source-code is the same, on some Orgs we use different ApiVersion, e.g. some Orgs use v45.0, others use v42.0 and others use v40.0.

We are using Schema methods to get existent fieldnames dynamically from a different utility-class called xs.cls currently running on all Orgs on v42.0

Now retrieving a list of available fields with xs.cls brings a list of fields for v42.0 - fine. Using the fields insinde query in myClass.cls might break, if the ApiVersion is different. Not always but sometimes. E.g. I'm getting for the standard SObject Contact a list of fields with Schema function in v42.0 which contains a standard field called IndividualId which did not exist back in v40.0, hence this would break. Please see this only as an example. I'm not interested in any specific solution for this. The example is just to illustrate the question and make it easier to understand.

So fixing this is easy: just keep all the classes using the same ApiVersion and all will be fine. I know this and this is not the answer I am looking for.

In some cases I would prefer keeping different ApiVersions on purpose.

Therefore I would be interested, if there is a way to determine the "current" ApiVersion at runtime dynamically at any place in my code. Knowing that we have different versions in parallel use, this method should report the current effective ApiVersion even in case when myClass.cls is using xs.cls or anyClass.cls is unsing anyOtherClass.cls with all classes having random ApiVersions?

If I would have an option to "see" on which Version im currently running, I could do whatever is necessary to do inside an if() statement dynamically.

Currently one idea might be, to brute-force known version differences and provoking version-specific exceptions by catching and handling them, but this is very odd and would make the code hard to read and messy.

1 Answer 1

3

I do not believe Apex provides a way to get this info directly, but by parsing an exception stack trace and querying ApexClass, we can do so. Since every class can have a different API version, this method returns the caller's API Version; add it to your favorite Utility class.

public static Decimal getCallersApexVersion() {
  try {
    Integer x = 1 / 0;
  }
  catch (Exception e) {
    // stack trace should never be null
    List<String> lines = e.getStackTraceString().split('\n');
    // Caller is line 1; format is method: line/column
    List<String> parts = lines[1].split(':'); 
    // Class.[namespace.]Classname.method or Trigger.[namespace.]Triggername.method
    List<String> methodParts = parts[0].split('\\.');  
    String ns;
    String className;
    if (methodParts.size() == 3) {
      className = methodParts[1];
    }
    else if (methodParts.size() == 4) {
      ns = methodParts[1];
      className = methodParts[2];
    }
    else {
      system.debug('Could not determine class name; method id=' + parts[0]);
      return null;     // probably anonymous apex
    }

    List<ApexClass> classRecords = [SELECT ApiVersion FROM ApexClass WHERE NamespacePrefix = :ns AND Name = :className];
    if (classRecords.size() == 0) {
      system.debug('Could not find class named ' + className + ' in namespace ' + ns);
    }
    return classRecords[0].ApiVersion;
  }
  return null;
}

If you only want to get the API version of the current class, change lines[1] to lines[0] in the definition of parts.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .