Salesforce Developers Blog

Retrieving all records with errors from a Bulk API job

Avatar for Jesper JoergensenJesper Joergensen
With the Summer ’10 release, we have added the ability to retrieve the original data that you send in a Bulk API batch. We keep this data around for 7 days just as we keep the job info, batch info and batch result files.
June 16, 2010
Listen to this article
0:00 / 0:00

With the Summer ’10 release, we have added the ability to retrieve the original data that you send in a Bulk API batch. We keep this data around for 7 days just as we keep the job info, batch info and batch result files.

Because you can now directly retrieve the original data, it has become easier to do things like building a CSV file of all records with errors. You can do this without keeping track of the mappings between the original data set and the batches you submitted to the job.

Here is a very simple Java sample showing how you can do this:  

import java.io.File;
import java.io.FileWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import com.sforce.async.CSVReader;
import com.sforce.async.BatchInfo;
import com.sforce.async.RestConnection;
import com.sforce.soap.partner.PartnerConnection;
import com.sforce.ws.ConnectorConfig;
public class GetErrors {
/**
* @param args
*/
public static void main(String[] args) {
try {
String username = args[0];
String password = args[1];
String jobId = args[2];
ConnectorConfig config = new ConnectorConfig();
config.setAuthEndpoint("https://login.salesforce.com/services/Soap/u/19");
config.setUsername(username);
config.setPassword(password);
// Instantiating a new partner connection will perform
// API login and set the session ID in the ConnectorConfig.
// We don't actually need the PartnerConnection itself.
PartnerConnection p = new PartnerConnection(config);
// Build REST API endpoint from Partner endpoint
String restEndpoint = config.getServiceEndpoint().substring(0, config.getServiceEndpoint().indexOf("Soap"))
+ "async/19";
config.setRestEndpoint(restEndpoint);
RestConnection rc = new RestConnection(config);
FileWriter out = new FileWriter(new File("errors.csv"));
boolean headerWritten = false;
for (BatchInfo b : rc.getBatchInfoList(jobId).getBatchInfo()) {
if (b.getState().equals(BatchStateEnum.Completed) && b.getNumberRecordsFailed() > 0) {
URL resultURL = new URL(restEndpoint + "/job/" + jobId + "/batch/" + b.getId() + "/result");
URL requestURL = new URL(restEndpoint + "/job/" + jobId + "/batch/" + b.getId() + "/request");
HttpURLConnection resultC = (HttpURLConnection) resultURL.openConnection();
HttpURLConnection requestC = (HttpURLConnection) requestURL.openConnection();
resultC.setRequestMethod("GET");
requestC.setRequestMethod("GET");
resultC.addRequestProperty("X-SFDC-Session", config.getSessionId());
requestC.addRequestProperty("X-SFDC-Session", config.getSessionId());
CSVReader resultR = new CSVReader(resultC.getInputStream());
CSVReader requestR = new CSVReader(requestC.getInputStream());
ArrayList resultHeader = resultR.nextRecord();
ArrayList requestHeader = requestR.nextRecord();
while (true) {
ArrayList resultRow = resultR.nextRecord();
ArrayList requestRow = requestR.nextRecord();
if (resultRow == null) {
if (requestRow != null) {
System.out.println("Result list finish before request list in batch " + b.getId());
}
break;
}
if (resultRow.get(1).equals("false")) {
if (!headerWritten) {
// We don't write out the header until we have at least one error record
for (String name : requestHeader) {
out.write(""" + name.replace(""", """") + "",");
}
out.write(""errors"n");
headerWritten = true;
}
for (String field : requestRow) {
if (field == null) {
out.write(",");
} else {
out.write(""" + field.replace(""", """") + "",");
}
}
if (resultRow.get(3) != null) {
out.write(""" + resultRow.get(3).replace(""", """") + ""n");
} else {
out.write("NO ERROR MESSAGEn");
}
}
}
}
}
out.flush();
out.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

You’ll need wsc-19 and a v19 partner jar to run it. Currently the WSC site doesn’t have the partner jar, but you can compile it yourself using WSC and a downloaded partner WSDL file from your org.

  1. Download a partner WSDL file by logging into your org and go to Setup -> Develop -> API -> Partner WSDL.
  2. Run something like: java -cp wsc-19.jar com.sforce.ws.tools.wsdlc `pwd`/partner.wsdl `pwd`/partner-19.jar
  3. Compile the class above and execute it with: java -cp wsc-19.jar:partner-19.jar GetErrors [sfdc_username] [sfdc_password] [jobId]
  4. The errors will be downloaded into errors.csv. The last column in the file will contain the error message for each row.

Disclaimer: I hacked this together pretty quickly and I haven’t done much testing. This is just meant as an example. If you put this into use, make sure you review and test your code thoroughly.

Also, note that the records will not be ordered the same way as in your original data set.

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS

More Blog Posts

Enabling MFA in MuleSoft for CI/CD Pipelines Using GitHub Actions

Enabling MFA in MuleSoft for CI/CD Pipelines Using GitHub Actions

Learn how to set up a GitHub Actions pipeline to work with your MFA-enabled account from Anypoint Platform.August 29, 2023

Building AI-Powered Apps with LLMs and Einstein

Building AI-Powered Apps with LLMs and Einstein

Learn how to build trusted AI applications with large language model APIs, dynamic grounding, prompt templates, and AI-powered orchestration.August 31, 2023

Invoke REST APIs with the Salesforce Integration User and OAuth Client Credentials

Invoke REST APIs with the Salesforce Integration User and OAuth Client Credentials

Learn to configure the Salesforce Integration User for both authentication using OAuth Client Credentials and authorization using permission sets.February 08, 2024