Add --strict so failures report a non-zero exit code
Every error path did printStackTrace() then System.exit(0), making a failed run indistinguishable from a successful one to any caller checking $?. pipekit works around this by grepping stdout for stack-trace text (_detect_silent_failure); 112 /opt/sync scripts run under `set -e` and cannot detect a jrunner failure at all. All 14 error exits now route through die(), which honours --strict. Opt-in rather than default: flipping it unconditionally would change the behaviour of those 112 scripts at once. --strict is pre-scanned from argv so it applies to failures during argument parsing too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e3f624f4d8
commit
61b3967a36
@ -70,6 +70,7 @@ public class jrunner {
|
||||
msg = msg + nl + "-b bulk copy into destination (SQL Server dest only)";
|
||||
msg = msg + nl + "-f output format (csv, tsv, table, json) - default: csv";
|
||||
msg = msg + nl + "--passfile path to the connection alias file - default: ~/.jrunnerpass";
|
||||
msg = msg + nl + "--strict exit 1 on failure (default exits 0, for legacy callers)";
|
||||
msg = msg + nl + "--help info";
|
||||
msg = msg + nl + "";
|
||||
msg = msg + nl + "Prefer -sc/-dc aliases over -scp/-dcp: a password given on the";
|
||||
@ -83,6 +84,12 @@ public class jrunner {
|
||||
|
||||
//---------------------------------------parse args into variables-------------------------------------------------
|
||||
|
||||
// Pre-scan: -sq can fail while the loop is still running, and it must
|
||||
// honour --strict regardless of where the flag sits in argv.
|
||||
for (String a : args) {
|
||||
if (a.equals("--strict")) strictExit = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < args.length; i = i +1 ){
|
||||
switch (args[i]) {
|
||||
//source connection alias
|
||||
@ -126,7 +133,7 @@ public class jrunner {
|
||||
catch (Exception e) {
|
||||
//System.out.println(nl + "error reasing source sql file: " + printStackTrace());
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -150,6 +157,9 @@ public class jrunner {
|
||||
case "--passfile":
|
||||
passFilePath = args[i+1];
|
||||
break;
|
||||
//exit non-zero on failure (handled in the pre-scan above)
|
||||
case "--strict":
|
||||
break;
|
||||
case "-v":
|
||||
System.out.println(msg);
|
||||
return;
|
||||
@ -223,7 +233,7 @@ public class jrunner {
|
||||
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
|
||||
} catch (ClassNotFoundException cnf) {
|
||||
System.out.println("The AS400 JDBC driver did not load");
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
|
||||
//-------------------------------------------establish connections-------------------------------------------------
|
||||
@ -245,7 +255,7 @@ public class jrunner {
|
||||
} catch (SQLException e) {
|
||||
System.out.println("issue connecting to source:");
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
if (!queryMode) {
|
||||
System.out.println(" ✅ source database");
|
||||
@ -257,7 +267,7 @@ public class jrunner {
|
||||
} catch (SQLException e) {
|
||||
System.out.println("issue connecting to destination:");
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
System.out.println(" ✅ destination database");
|
||||
}
|
||||
@ -276,7 +286,7 @@ public class jrunner {
|
||||
} catch (SQLException e) {
|
||||
System.out.println("issue retrieving rows from source:");
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
|
||||
//---------------------------------------build meta---------------------------------------------------------------
|
||||
@ -290,7 +300,7 @@ public class jrunner {
|
||||
dtn = new String[cols + 1];
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
try {
|
||||
for (int i = 1; i <= cols; i++){
|
||||
@ -301,7 +311,7 @@ public class jrunner {
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
//-------------------------clear the target table if requeted----------------------------------------------------
|
||||
if (!queryMode && clear) {
|
||||
@ -314,7 +324,7 @@ public class jrunner {
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println(sql);
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
}
|
||||
if (queryMode) {
|
||||
@ -323,7 +333,7 @@ public class jrunner {
|
||||
outputQueryResults(rs, cols, dtn, outputFormat);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
} else if (bulk && dcu.toLowerCase().startsWith("jdbc:sqlserver:")) {
|
||||
//-------------------------------bulk copy (SQL Server dest)-------------------------------------------------
|
||||
@ -347,7 +357,7 @@ public class jrunner {
|
||||
System.out.print("\r" + src.rowsWritten());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
} else if (bulk && dcu.toLowerCase().startsWith("jdbc:postgresql:")) {
|
||||
//-------------------------------bulk copy (COPY, Postgres dest)--------------------------------------------
|
||||
@ -389,7 +399,7 @@ public class jrunner {
|
||||
System.out.print("\r" + rows);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
} else {
|
||||
System.out.println("------------row count-------------------------------------");
|
||||
@ -523,7 +533,7 @@ public class jrunner {
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println(sql);
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
sql = "";
|
||||
}
|
||||
@ -538,12 +548,12 @@ public class jrunner {
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.out.println(sql);
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
System.exit(0);
|
||||
die();
|
||||
}
|
||||
}
|
||||
//System.out.println(sql);
|
||||
@ -767,6 +777,17 @@ public class jrunner {
|
||||
return value;
|
||||
}
|
||||
|
||||
// Historically every error path did printStackTrace() then System.exit(0),
|
||||
// so a failed run was indistinguishable from a successful one to any
|
||||
// caller checking $?. 112 /opt/sync scripts run under `set -e` against
|
||||
// that behaviour, so flipping it unconditionally would change them all at
|
||||
// once; --strict makes the correct exit code opt-in until they're audited.
|
||||
private static boolean strictExit = false;
|
||||
|
||||
private static void die() {
|
||||
System.exit(strictExit ? 1 : 0);
|
||||
}
|
||||
|
||||
private static String escapeTSV(String value) {
|
||||
return value.replaceAll("\t", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user