Skip to content

Commit

Permalink
multiple exit error codes for batch (CLI) mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ashitsalesforce committed Jan 16, 2024
1 parent 3d25d2b commit 020cb5b
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ public final void execute() {
exceptions.add(e);
}
try {
if (this.errorWriter != null) {
getMonitor().setNumberRowsWithError(this.errorWriter.getCurrentRowNumber());
}
//if no exceptions occurred then display success/error
if (exceptions.size() == 0) {
final Object[] args = {String.valueOf(getVisitor().getNumberSuccesses()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ public interface ILoaderProgress {
String getMessage();
void setNumberBatchesTotal(int numberBatchesTotal);
int getNumberBatchesTotal();
void setNumberRowsWithError(int rowsWithError);
int getNumberRowsWithError();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static NihilistProgressAdapter get() {
//logger
private final Logger logger = LogManager.getLogger(getClass());
private String message = "";
private int numRowsWithError = 0;

@Override
public void beginTask(String name, int totalWork) {
Expand Down Expand Up @@ -110,4 +111,15 @@ public int getNumberBatchesTotal() {
return this.numberBatchesTotal;
}

@Override
public void setNumberRowsWithError(int rowsWithError) {
this.numRowsWithError = rowsWithError;

}

@Override
public int getNumberRowsWithError() {
return this.numRowsWithError;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class SWTProgressAdapter implements ILoaderProgress {
private String dispMessage;
private final Controller controller;
private boolean success = false;
private int numRowsWithError = 0;

public SWTProgressAdapter(IProgressMonitor monitor_, Controller controller) {
monitor = monitor_;
Expand Down Expand Up @@ -163,4 +164,15 @@ public int getNumberBatchesTotal() {
return this.numberBatchesTotal;
}

@Override
public void setNumberRowsWithError(int rowsWithError) {
this.numRowsWithError = rowsWithError;

}

@Override
public int getNumberRowsWithError() {
return this.numRowsWithError;
}

}
3 changes: 3 additions & 0 deletions src/main/java/com/salesforce/dataloader/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ public class Config {
public static final String ENCRYPTION_KEY_FILE = "process.encryptionKeyFile"; //$NON-NLS-1$
public static final String PROCESS_THREAD_NAME = "process.thread.name";
public static final String PROCESS_KEEP_ACCOUNT_TEAM = "process.keepAccountTeam";
public static final String PROCESS_EXIT_WITH_ERROR_ON_FAILED_ROWS_BATCH_MODE = "process.batchMode.exitWithErrorOnFailedRows";

// data access configuration (e.g., for CSV file, database, etc).
public static final String DAO_TYPE = "dataAccess.type"; //$NON-NLS-1$
Expand Down Expand Up @@ -441,6 +442,7 @@ public class Config {
WIRE_OUTPUT,
PROCESS_THREAD_NAME,
PROCESS_BULK_CACHE_DATA_FROM_DAO,
PROCESS_EXIT_WITH_ERROR_ON_FAILED_ROWS_BATCH_MODE,
SAVE_BULK_SERVER_LOAD_AND_RAW_RESULTS_IN_CSV,
API_VERSION_PROP,
READ_CHARSET,
Expand Down Expand Up @@ -608,6 +610,7 @@ private void setDefaults() {
setDefaultValue(LIMIT_OUTPUT_TO_QUERY_FIELDS, true);
setDefaultValue(WIZARD_CLOSE_ON_FINISH, true);
setDefaultValue(CACHE_DESCRIBE_GLOBAL_RESULTS, true);
setDefaultValue(PROCESS_EXIT_WITH_ERROR_ON_FAILED_ROWS_BATCH_MODE, false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ public static void install(String[] args) {
createAppsDirShortcut(installationDir);
}
if (!skipCopyArtifacts) {
System.exit(0);
System.exit(AppUtil.EXIT_CODE_NO_ERRORS);
}
} catch (Exception ex) {
handleException(ex, Level.FATAL);
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
}

Expand Down Expand Up @@ -151,7 +151,7 @@ private static void copyArtifacts(String installationDir) throws Exception {
logger.debug("going to delete " + installationDir);
FileUtils.deleteDirectory(new File(installationDir));
} else {
System.exit(0);
System.exit(AppUtil.EXIT_CODE_NO_ERRORS);
}
}
String installationSourceDir = ".";
Expand All @@ -172,7 +172,7 @@ private static void copyArtifacts(String installationDir) throws Exception {
}
if (dataloaderJar == null) {
logger.fatal("Did not find Data Loader jar in the installation artifacts. Unable to install Data Loader");
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
FileUtils.copyFileToDirectory(new File(dataloaderJar), new File(installationDir));
logger.debug("going to delete \\.* files from " + installationDir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.salesforce.dataloader.security.EncryptionUtil;
import com.salesforce.dataloader.ui.UIUtils;
import com.salesforce.dataloader.util.AppUtil;
import com.salesforce.dataloader.util.ExitException;

import java.io.File;
import java.io.FileFilter;
Expand All @@ -59,6 +60,7 @@ public class DataLoaderRunner extends Thread {
private static final String PATH_SEPARATOR = System.getProperty("path.separator");
private static final String FILE_SEPARATOR = System.getProperty("file.separator");
private static Logger logger;
private static int exitCode = AppUtil.EXIT_CODE_NO_ERRORS;

public void run() {
// called just before the program closes
Expand All @@ -68,11 +70,15 @@ public void run() {
public static void main(String[] args) {
try {
runApp(args, null);
System.exit(exitCode);
} catch (ExitException ex) {
System.exit(ex.getExitCode());
} finally {
if (logger != null) {
logger.debug("Number of server API invocations = " + HttpClientTransport.getServerInvocationCount());
}
}
System.exit(exitCode);
}

public static IProcess runApp(String[] args, ILoaderProgress monitor) {
Expand All @@ -81,14 +87,10 @@ public static IProcess runApp(String[] args, ILoaderProgress monitor) {
args = AppUtil.initializeAppConfig(args);
} catch (FactoryConfigurationError | Exception ex) {
ex.printStackTrace();
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
if (AppUtil.getAppRunMode() == AppUtil.APP_RUN_MODE.BATCH) {
try {
return ProcessRunner.runBatchMode(AppUtil.convertCommandArgsArrayToArgMap(args), monitor);
} catch (Throwable t) {
ProcessRunner.logErrorAndExitProcess("Unable to run process", t);
}
return ProcessRunner.runBatchMode(AppUtil.convertCommandArgsArrayToArgMap(args), monitor);
} else if (AppUtil.getAppRunMode() == AppUtil.APP_RUN_MODE.ENCRYPT) {
EncryptionUtil.main(args);
} else {
Expand Down Expand Up @@ -118,6 +120,10 @@ public static IProcess runApp(String[] args, ILoaderProgress monitor) {
return null;
}

public static void setExitCode(int codeVal) {
exitCode = codeVal;
}

private static void rerunWithSWTNativeLib(String[] args) {
String javaExecutablePath = null;
try {
Expand Down Expand Up @@ -153,7 +159,7 @@ private static void rerunWithSWTNativeLib(String[] args) {
logger.error("Unable to find SWT jar for "
+ System.getProperty("os.name") + " : "
+ System.getProperty("os.arch"));
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}

// set classpath
Expand Down
44 changes: 33 additions & 11 deletions src/main/java/com/salesforce/dataloader/process/ProcessRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import com.salesforce.dataloader.exception.ProcessInitializationException;
import com.salesforce.dataloader.ui.Labels;
import com.salesforce.dataloader.util.AppUtil;
import com.salesforce.dataloader.util.ExitException;
import com.salesforce.dataloader.util.OAuthBrowserLoginRunner;
import com.sforce.soap.partner.fault.ApiFault;

Expand Down Expand Up @@ -236,13 +237,22 @@ public void afterPropertiesSet() throws Exception {
}
}

public static void logErrorAndExitProcess(String message, Throwable err) {
if (logger == null || err == null) {
System.err.println(message);
throw new RuntimeException(message);
} else {
logger.fatal(message, err);
throw new RuntimeException(err.getMessage());
public static void logErrorAndExitProcess(String message, Throwable throwable, int exitCode) {
if (throwable == null) {
if (logger == null) {
System.err.println(message);
} else {
logger.fatal(message);
}
throw new ExitException(message, exitCode); // expect caller to exit
} else { // throwable != null
if (logger == null) {
System.err.println(throwable.getMessage());
throwable.printStackTrace();
} else {
logger.fatal(message, throwable);
}
throw new ExitException(throwable, exitCode);
}
}

Expand All @@ -253,21 +263,33 @@ public static ProcessRunner runBatchMode(Map<String, String>argMap, ILoaderProgr
// create the process
runner = ProcessRunner.getInstance(argMap);
if (runner == null) {
logErrorAndExitProcess("Process runner is null", new NullPointerException());
logErrorAndExitProcess("Process runner is null",
new NullPointerException(), AppUtil.EXIT_CODE_CLIENT_ERROR);
}
// run the process
runner.run(progressMonitor);
progressMonitor = runner.getMonitor();
if (progressMonitor != null && (progressMonitor.isCanceled() || !progressMonitor.isSuccess())) {
logErrorAndExitProcess(progressMonitor.getMessage(), null);
if (progressMonitor != null) {
if (progressMonitor.isCanceled()) {
logErrorAndExitProcess(progressMonitor.getMessage(), null, AppUtil.EXIT_CODE_CLIENT_ERROR);
} else if (!progressMonitor.isSuccess()) {
logErrorAndExitProcess(progressMonitor.getMessage(), null, AppUtil.EXIT_CODE_SERVER_ERROR);
} else if (Config.getCurrentConfig() != null
&& Config.getCurrentConfig().getBoolean(Config.PROCESS_EXIT_WITH_ERROR_ON_FAILED_ROWS_BATCH_MODE)
&& progressMonitor.getNumberRowsWithError() > 0) {
DataLoaderRunner.setExitCode(AppUtil.EXIT_CODE_RESULTS_ERROR);
}
}
} catch (Throwable t) {
if (t.getClass().equals(UnsupportedOperationException.class)) {
// this is done to allow integration tests to continue
// after a negative test of an operation results in an exception
throw (UnsupportedOperationException)t;
}
logErrorAndExitProcess("Unable to run process", t);
if (t.getClass().equals(ExitException.class)) {
throw (ExitException)t;
}
logErrorAndExitProcess("Unable to run process", t, AppUtil.EXIT_CODE_OPERATION_ERROR);
}
return runner;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

import java.security.GeneralSecurityException;

import com.salesforce.dataloader.util.AppUtil;

public class EncryptionUtil {

/**
Expand Down Expand Up @@ -85,20 +87,20 @@ public static void main(String[] args) {
// args[1] = key (optional)
if (args.length < 1) {
printUsage();
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}

int i = 0;
String option = args[i];
if (option.length() < 2 || option.charAt(0) != '-') {
System.out.println("Invalid option format: " + args[i]);
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
// make sure enough arguments are provided
if (arrayTooSmall(args, i) && option.charAt(1) != 'k') {
System.out.println("Option '" + option + "' requires at least one parameter. Please check usage.\n");
printUsage();
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
// advance index to param and save the param value
String param = null;
Expand All @@ -113,15 +115,15 @@ public static void main(String[] args) {
} catch (Exception e) {
System.out.println("Error setting the key from file: "
+ keyFilename + ", error: " + e.getMessage());
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
}
try {
String encrypted = enc.encryptMsg(param);
System.out.println("The output string of encryption is: \n" + encrypted);
} catch (Exception e) {
System.out.println("Error setting the key: " + e.getMessage());
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}

break;
Expand All @@ -136,7 +138,7 @@ public static void main(String[] args) {
} else {
System.out.println("Please provide correct parameters!");
printUsage();
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
} catch (Exception e) {
System.out.println("Error occurred: " + e.getMessage());
Expand All @@ -152,22 +154,22 @@ public static void main(String[] args) {
encAes.setCipherKeyFromFilePath(keyFilename);
} catch (GeneralSecurityException e) {
System.out.println("Failed in decryption: " + e.getMessage() + "\n Make sure using the same keyfile to decrypt.");
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
}
try {
String plainText = encAes.decryptMsg(encryptMsg);
System.out.println("The output string of decryption is: \n" + plainText);
} catch (Exception e) {
System.out.println("Failed in decryption: " + e.getMessage() + "\n Make sure using the same keyfile to decrypt.");
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
break;

default:
System.out.println("Unsupported option: " + option);
printUsage();
System.exit(-1);
System.exit(AppUtil.EXIT_CODE_CLIENT_ERROR);
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/main/java/com/salesforce/dataloader/util/AppUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ public enum APP_RUN_MODE {
public static final String CLI_OPTION_CONFIG_DIR_PROP = "salesforce.config.dir";
public static final String CONFIG_DIR_DEFAULT_VALUE = "configs";
public static final String DATALOADER_DOWNLOAD_URL = "https://developer.salesforce.com/tools/data-loader";
public static final int EXIT_CODE_NO_ERRORS = 0;
public static final int EXIT_CODE_CLIENT_ERROR = 1;
public static final int EXIT_CODE_SERVER_ERROR = 2;
public static final int EXIT_CODE_OPERATION_ERROR = 3;
public static final int EXIT_CODE_RESULTS_ERROR = 4;

private static APP_RUN_MODE appRunMode = APP_RUN_MODE.UI;
private static Logger logger = null;
Expand All @@ -109,7 +114,7 @@ public enum APP_RUN_MODE {
versionProps.load(AppUtil.class.getClassLoader().getResourceAsStream("com/salesforce/dataloader/version.properties"));
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
System.exit(EXIT_CODE_CLIENT_ERROR);
}

DATALOADER_VERSION=versionProps.getProperty("dataloader.version");
Expand Down Expand Up @@ -346,7 +351,7 @@ private static void processArgsForBatchMode(String[] args, Map<String,String> ar
+ " for example:\n"
+ "\n"
+ " process ../myconfigdir");
System.exit(-1);
System.exit(EXIT_CODE_CLIENT_ERROR);
}
if (!argsMap.containsKey(AppUtil.CLI_OPTION_CONFIG_DIR_PROP)) {
argsMap.put(AppUtil.CLI_OPTION_CONFIG_DIR_PROP, args[0]);
Expand Down
Loading

0 comments on commit 020cb5b

Please sign in to comment.