Exceptions

Exceptions
Apex uses the familiar throw, try, catch and finally statements to handle exception flows. For example:
Try {
Throw new Exception();
} catch (ListException e) {
//List Exception handling code here
} catch(Exception e) {
//Generic exception handling code here
}

Using the DmlException exception

  1. Account[] accts = new Account[]{new Account(billingcity = 'San Jose')}; 
  2. try { 
  3.  insert accts; 
  4. } catch (System.DmlException e) { 
  5.     for (Integer i = 0; i < e.getNumDml(); i++) { 
  6.     // Process exception here 
  7.     System.debug(e.getDmlMessage(i)); 
  8.     } 
  9.   }
Returns the value of the System.StatusCode enum
  1. try { 
  2. insert new Account(); 
  3. } catch (System.DmlException ex) { 
  4.   System.assertEquals( StatusCode.REQUIRED_FIELD_MISSING,       ex.getDmlType(0)); 
  5.   }
Sending an Email on exception
  1. try{
  2. update account;
  3. } catch (DMLException e){
  4. ApexPages.addMessages(e);
  5. Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage();
  6. String[] toAddresses = new String[] {'developer@acme.com'};
  7. mail.setToAddresses(toAddresses);
  8. mail.setReplyTo('developer@acme.com');
  9. mail.setSenderDisplayName('Apex error message');
  10. mail.setSubject('Error from Org : ' + UserInfo.getOrganizationName());
  11. mail.setPlainTextBody(e.getMessage());
  12. Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
  13. }

Test Cases:

Query:
I have an Apex Class, where 55% of the code is inside a catch, requiring a DML exception to be executed. Since the DML update request is using data from an SOQL request inside this class, I have no idea how I can trigger a DML exception.
Is it possible to lock a certain record from updating (or all the database), in a way that could trigger a DML exception?
Answer:
You can use FOR UPDATE to lock a certain record, but it would be locked to the testing transaction, so it might not give you the DML Exception you want.
How dependant are you on the content of the DML Exception? If you just want an exception of the correct type use Test.isRunningTest() to deliberately cause the exception.
try {

    // If you can't manipulate the Apex methods input or database state to cause a
    // DMLExcpetion then you can deliberately cause the DMLException to improve your
    // code coverage and check the functionality of the exception handling.
    // You could also use a flag set from your test method to indicate that the 
    // exception should be thrown
    if(Test.isRunningTest()) {
        // Cause DMLException
        insert new Lead();
    }

} catch (DMLException ex) {
    // Existing exception handling.        
}
As you mentioned, it is less than ideal to modify the body of the Apex Method you are testing to facilitate testing. If you can, manipulate either the methods inputs or the state of the database from the test method to cause the DMLException.
You mentioned that the update is using data that is retrieved from a SOQL request in the class. If you put the test method within the class definition you can manipulate the private members directly from the test.

Comments

Popular Posts