Result
The DML library provides comprehensive result handling through the Result, OperationResult, RecordResult, and Error interfaces. These allow you to inspect the outcome of DML operations, including success/failure status, record IDs, and error details.
Overview
When you call commitWork() or dryRun(), a Result object is returned containing detailed information about each DML operation performed.
DML.Result result = new DML()
.toInsert(account)
.toUpdate(contact)
.commitWork();
// Check results by operation type
List<DML.OperationResult> insertResults = result.inserts();
List<DML.OperationResult> updateResults = result.updates();
// Check results by SObject type
DML.OperationResult accountInserts = result.insertsOf(Account.SObjectType);Result Interface
The Result interface provides methods to access operation results.
Get All Results
Signature
List<OperationResult> all();Example
DML.Result result = new DML()
.toInsert(accounts)
.toUpdate(contacts)
.commitWork();
for (DML.OperationResult opResult : result.all()) {
System.debug('Operation: ' + opResult.operationType());
System.debug('Object: ' + opResult.objectType());
System.debug('Has Failures: ' + opResult.hasFailures());
}Get Results by Operation Type
Signatures
List<OperationResult> inserts();
List<OperationResult> updates();
List<OperationResult> upserts();
List<OperationResult> deletes();
List<OperationResult> undeletes();
List<OperationResult> events();Example
DML.Result result = new DML()
.toInsert(accounts)
.toInsert(contacts)
.commitWork();
// Get all insert results (one per SObject type)
List<DML.OperationResult> insertResults = result.inserts();
Assert.areEqual(2, insertResults.size()); // Account and ContactGet Results by SObject Type
Signatures
OperationResult insertsOf(Schema.SObjectType objectType);
OperationResult updatesOf(Schema.SObjectType objectType);
OperationResult upsertsOf(Schema.SObjectType objectType);
OperationResult deletesOf(Schema.SObjectType objectType);
OperationResult undeletesOf(Schema.SObjectType objectType);
OperationResult eventsOf(Schema.SObjectType objectType);Example
DML.Result result = new DML()
.toInsert(accounts)
.toInsert(contacts)
.commitWork();
// Get insert results for Accounts only
DML.OperationResult accountResults = result.insertsOf(Account.SObjectType);
DML.OperationResult contactResults = result.insertsOf(Contact.SObjectType);OperationResult Interface
The OperationResult interface provides detailed information about a specific DML operation.
Methods
Signatures
OperationType operationType(); // DML operation type (INSERT_DML, UPDATE_DML, etc.)
Schema.SObjectType objectType(); // SObject type for this operation
Boolean hasFailures(); // True if any records failed
List<Error> errors(); // All errors from failed records
List<SObject> records(); // All records that were processed
List<SObject> successes(); // Records that succeeded
List<SObject> failures(); // Records that failed
List<RecordResult> recordResults(); // Individual record resultsExample
DML.Result result = new DML()
.toInsert(accounts)
.commitWork();
DML.OperationResult opResult = result.insertsOf(Account.SObjectType);
// Operation metadata
Assert.areEqual(DML.OperationType.INSERT_DML, opResult.operationType());
Assert.areEqual(Account.SObjectType, opResult.objectType());
// Check for failures
if (opResult.hasFailures()) {
List<SObject> failedRecords = opResult.failures();
List<DML.Error> allErrors = opResult.errors();
}
// Get successful records
List<SObject> successfulRecords = opResult.successes();RecordResult Interface
The RecordResult interface provides information about individual record processing.
Methods
Signatures
Id id(); // Record ID (assigned after insert)
SObject record(); // The actual SObject record
Boolean isSuccess(); // True if this record succeeded
List<Error> errors(); // List of errors for this recordExample
DML.Result result = new DML()
.toInsert(accounts)
.allowPartialSuccess()
.commitWork();
DML.OperationResult opResult = result.insertsOf(Account.SObjectType);
for (DML.RecordResult recordResult : opResult.recordResults()) {
if (recordResult.isSuccess()) {
System.debug('Record inserted with Id: ' + recordResult.id());
System.debug('Record: ' + recordResult.record());
} else {
System.debug('Record failed:');
for (DML.Error error : recordResult.errors()) {
System.debug(' - ' + error.message());
}
}
}Error Interface
The Error interface provides details about DML errors.
Methods
Signatures
String message(); // Error message
System.StatusCode statusCode(); // Status code (e.g., REQUIRED_FIELD_MISSING)
List<String> fields(); // Fields that caused the errorExample
DML.Result result = new DML()
.toInsert(accounts)
.allowPartialSuccess()
.commitWork();
for (DML.OperationResult opResult : result.all()) {
for (DML.Error error : opResult.errors()) {
System.debug('Error Message: ' + error.message());
System.debug('Status Code: ' + error.statusCode());
System.debug('Fields: ' + error.fields());
}
}OperationType Enum
The DML.OperationType enum identifies the type of DML operation.
Values
DML.OperationType.INSERT_DML
DML.OperationType.UPDATE_DML
DML.OperationType.UPSERT_DML
DML.OperationType.DELETE_DML
DML.OperationType.UNDELETE_DML
DML.OperationType.PUBLISH_DMLComplete Examples
Basic Insert with Result
Account account = new Account(Name = 'Test Account');
DML.Result result = new DML()
.toInsert(account)
.commitWork();
// Verify result
Assert.areEqual(1, result.inserts().size());
DML.OperationResult opResult = result.insertsOf(Account.SObjectType);
Assert.areEqual(1, opResult.records().size());
Assert.areEqual(1, opResult.successes().size());
Assert.areEqual(0, opResult.failures().size());
Assert.isFalse(opResult.hasFailures());
Assert.areEqual(DML.OperationType.INSERT_DML, opResult.operationType());
Assert.areEqual(Account.SObjectType, opResult.objectType());
// Check record result
DML.RecordResult recordResult = opResult.recordResults()[0];
Assert.isTrue(recordResult.isSuccess());
Assert.isNotNull(recordResult.id());
Assert.areEqual(account.Id, recordResult.id());Partial Success Handling
List<Account> accounts = new List<Account>{
new Account(Name = 'Valid Account 1'),
new Account(), // Missing required Name
new Account(Name = 'Valid Account 2')
};
DML.Result result = new DML()
.toInsert(accounts)
.allowPartialSuccess()
.commitWork();
DML.OperationResult opResult = result.insertsOf(Account.SObjectType);
// Check counts
Assert.areEqual(3, opResult.records().size());
Assert.areEqual(2, opResult.successes().size());
Assert.areEqual(1, opResult.failures().size());
Assert.isTrue(opResult.hasFailures());
// Process individual results
for (DML.RecordResult rr : opResult.recordResults()) {
if (rr.isSuccess()) {
System.debug('Record succeeded with Id: ' + rr.id());
} else {
System.debug('Record failed:');
for (DML.Error error : rr.errors()) {
System.debug(' Status: ' + error.statusCode());
System.debug(' Message: ' + error.message());
System.debug(' Fields: ' + error.fields());
}
}
}Multiple Operation Types
Account account = new Account(Name = 'New Account');
Contact existingContact = [SELECT Id, FirstName FROM Contact LIMIT 1];
existingContact.FirstName = 'Updated';
Lead leadToDelete = [SELECT Id FROM Lead LIMIT 1];
DML.Result result = new DML()
.toInsert(account)
.toUpdate(existingContact)
.toDelete(leadToDelete)
.commitWork();
// Check each operation type
Assert.areEqual(1, result.inserts().size());
Assert.areEqual(1, result.updates().size());
Assert.areEqual(1, result.deletes().size());
// Verify specific results
Assert.isFalse(result.insertsOf(Account.SObjectType).hasFailures());
Assert.isFalse(result.updatesOf(Contact.SObjectType).hasFailures());
Assert.isFalse(result.deletesOf(Lead.SObjectType).hasFailures());Multiple SObject Types Same Operation
Account account = new Account(Name = 'Test Account');
Contact contact = new Contact(FirstName = 'Test', LastName = 'Contact');
Lead lead = new Lead(FirstName = 'Test', LastName = 'Lead', Company = 'Test Co');
DML.Result result = new DML()
.toInsert(account)
.toInsert(contact)
.toInsert(lead)
.commitWork();
// Get all insert results (3 - one per SObject type)
List<DML.OperationResult> insertResults = result.inserts();
Assert.areEqual(3, insertResults.size());
// Get specific SObject type results
Assert.areEqual(1, result.insertsOf(Account.SObjectType).records().size());
Assert.areEqual(1, result.insertsOf(Contact.SObjectType).records().size());
Assert.areEqual(1, result.insertsOf(Lead.SObjectType).records().size());Dry Run Results
Account account = new Account(Name = 'Test Account');
DML.Result result = new DML()
.toInsert(account)
.dryRun();
// Result is returned but database is rolled back
Assert.areEqual(1, result.inserts().size());
Assert.isFalse(result.insertsOf(Account.SObjectType).hasFailures());
// No records in database
Assert.areEqual(0, [SELECT COUNT() FROM Account WHERE Name = 'Test Account']);Accessing Records from Results
List<Account> accounts = new List<Account>{
new Account(Name = 'Account 1'),
new Account(Name = 'Account 2'),
new Account(Name = 'Account 3')
};
DML.Result result = new DML()
.toInsert(accounts)
.commitWork();
// Get the records that were processed
List<SObject> processedRecords = result.insertsOf(Account.SObjectType).records();
// They're the same references, so IDs are populated
Assert.areEqual(3, processedRecords.size());
for (SObject record : processedRecords) {
Assert.isNotNull(record.Id);
}
// Get only successful records
List<SObject> successfulRecords = result.insertsOf(Account.SObjectType).successes();Best Practices
Always Check for Failures
DML.Result result = new DML()
.toInsert(records)
.allowPartialSuccess()
.commitWork();
for (DML.OperationResult opResult : result.all()) {
if (opResult.hasFailures()) {
// Handle failures appropriately
for (DML.Error error : opResult.errors()) {
System.debug('Error: ' + error.message());
}
}
}Use Results for Verification in Tests
@IsTest
static void testAccountCreation() {
Account account = new Account(Name = 'Test');
DML.Result result = new DML()
.toInsert(account)
.commitWork();
// Use result for comprehensive assertions
DML.OperationResult opResult = result.insertsOf(Account.SObjectType);
Assert.areEqual(1, opResult.records().size());
Assert.areEqual(1, opResult.successes().size());
Assert.areEqual(0, opResult.failures().size());
Assert.isFalse(opResult.hasFailures());
Assert.areEqual(DML.OperationType.INSERT_DML, opResult.operationType());
Assert.isNotNull(opResult.recordResults()[0].id());
}