defensive apex programming

21
Defensive Apex Programming Dan Appleman CTO Full Circle Insights, Author of Advanced Apex Programming [email protected] @danappleman

Upload: salesforce-developers

Post on 15-Feb-2017

1.014 views

Category:

Technology


0 download

TRANSCRIPT

Defensive Apex Programming

Dan Appleman

CTO – Full Circle Insights, Author of Advanced Apex Programming

[email protected]

@danappleman

What is the difference between a coder (“code monkey”) and a software developer?

Say what???

The Software Application Life-Cycle

Requirements

Design

Code

Test/QA/Doc

Maintenance

The Software Application Life-Cycle - Traditional

Requirements

Design

Code

Test/QA/Doc

Maintenance

• Bug fixes

• New OS version/browser

• Platform changes

• Regression testing of

changes by developers

• Critical features

The Software Application Life-Cycle – Salesforce Platform

Requirements

Design

Code

Test/QA/Doc

Maintenance

• Bug fixes

• Platform updates (3x per year)

• Regression testing of changes

by developers

• Critical features

• Metadata changes that

change the behavior of the

code.

Traditional Applications

Platform

Your App

Platform

Apex

Other declarative

metadata changes

Apex Applications

Defensive Apex Programming

Making a Future Call – The Wrong Way

public void CallFuture1()

{

vulnerableFutureCall();

}

@future

public static void vulnerableFutureCall()

{

// Do something here

}

Making a Future Call – The Wrong Way

public void CallFuture1()

{

vulnerableFutureCall();

}

@future

public static void vulnerableFutureCall()

{

// Do something here

}

• Other app calls this in a future context?

• Batch calls this?

• Other code makes future calls and we hit limit?

• An error occurs during the future call?

(you’ll never know it)

Defensive Future Callspublic void CallFuture2()

{

if(System.isFuture() || system.isBatch()) defensiveFutureCallSync();

else {

if(Limits.getFutureCalls()< Limits.getLimitFutureCalls())

defensiveFutureCallAsync();

else { // ????

}

}

}

@future

public static void defensiveFutureCallAsync()

{

defensiveFutureCallSync();

}

public static void defensiveFutureCallSync()

{

// Do something here

}

• Backs up to sync pattern (if applicable)

• Alternatives include try/catch & logging errors

instead

• Reliable async is a much bigger topic...

Using a Custom Setting – The Wrong Way

Boolean enabled = ConfigSettings__c.getInstance('default').Application_Enabled__c;

Guaranteed null reference exception on:

• Uninitialized orgs/sandboxes (metadata push)

• SeeAllData false tests on methods that don’t initialize setting

• SeeAllData false tests on managed package tests that can’t initialize

setting.

Defensive Custom Settings

private static ConfigSettings__c testConfig;

public static ConfigSettings__c getConfig()

{

if(Test.isRunningTest() && testConfig!=null) return testConfig;

ConfigSettings__c result = ConfigSettings__c.getInstance('default');

if(result==null)

{

result = new ConfigSettings__c(name='default', Application_Enabled__c= false);

}

if(Test.isRunningTest()) testConfig = result;

return result;

}

Then...

Boolean enabled = ConfigurationClass.getConfig().Application_Enabled__c;

• Can’t return null

• Protects from DML

errors on parallel tests

• Simplifies test setup

Detecting a Field Change

Demo

Updating Records – Watch For Concurrency Errors

update listOfRecords;

or

List<Database.SaveResult> dmlResults =

Database.Update(listOfRecords, false);

for(Integer x = 0; x< ops.size(); x++)

{

Database.SaveResult sr = dmlResults[x];

if(!sr.isSuccess())

{

for(Database.Error err: sr.getErrors())

{

if(err.getStatusCode() == StatusCode.UNABLE_TO_LOCK_ROW)

{

// Concurrency error

}

}

}

}

Variations include

• try/catch blocks

• setSavePoint/rollBack

• all or nothing

• Logging vs retry

You can’t defend against every metadata change!

Continuous Integration – In Traditional Software Development

Software

repositoryJenkins Build

Developer

Developer

Developer

Continuous Integration – In Salesforce Too!

OrgJenkins Build

Developer

Developer

Developer

Continuous Integration – In Salesforce Too!!!!!!!!!

Org

Developer

Developer

Developer

CI app

Continuous Integration – In Salesforce Too!!!!!!!!!

Org

Developer

Developer

Developer

CI app

Managed PackageCI App

Native TestTracker App

http://AdvancedApex.com/TestTracker

Free private managed package

Open Source

Questions?

Test Tracker tool

http://AdvancedApex.com/testtracker

For more information, see chapter the new chapter

12 “Maintaining Apex” of the just released third

edition.

Also check out:

Career Strategies and Opportunities for Salesforce

Platform Developers on pluralsight.com