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 + "-b bulk copy into destination (SQL Server dest only)";
|
||||||
msg = msg + nl + "-f output format (csv, tsv, table, json) - default: csv";
|
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 + "--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 + "--help info";
|
||||||
msg = msg + nl + "";
|
msg = msg + nl + "";
|
||||||
msg = msg + nl + "Prefer -sc/-dc aliases over -scp/-dcp: a password given on the";
|
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-------------------------------------------------
|
//---------------------------------------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 ){
|
for (int i = 0; i < args.length; i = i +1 ){
|
||||||
switch (args[i]) {
|
switch (args[i]) {
|
||||||
//source connection alias
|
//source connection alias
|
||||||
@ -126,7 +133,7 @@ public class jrunner {
|
|||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
//System.out.println(nl + "error reasing source sql file: " + printStackTrace());
|
//System.out.println(nl + "error reasing source sql file: " + printStackTrace());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -150,6 +157,9 @@ public class jrunner {
|
|||||||
case "--passfile":
|
case "--passfile":
|
||||||
passFilePath = args[i+1];
|
passFilePath = args[i+1];
|
||||||
break;
|
break;
|
||||||
|
//exit non-zero on failure (handled in the pre-scan above)
|
||||||
|
case "--strict":
|
||||||
|
break;
|
||||||
case "-v":
|
case "-v":
|
||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
return;
|
return;
|
||||||
@ -223,7 +233,7 @@ public class jrunner {
|
|||||||
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
|
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
|
||||||
} catch (ClassNotFoundException cnf) {
|
} catch (ClassNotFoundException cnf) {
|
||||||
System.out.println("The AS400 JDBC driver did not load");
|
System.out.println("The AS400 JDBC driver did not load");
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------establish connections-------------------------------------------------
|
//-------------------------------------------establish connections-------------------------------------------------
|
||||||
@ -245,7 +255,7 @@ public class jrunner {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.out.println("issue connecting to source:");
|
System.out.println("issue connecting to source:");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
if (!queryMode) {
|
if (!queryMode) {
|
||||||
System.out.println(" ✅ source database");
|
System.out.println(" ✅ source database");
|
||||||
@ -257,7 +267,7 @@ public class jrunner {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.out.println("issue connecting to destination:");
|
System.out.println("issue connecting to destination:");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
System.out.println(" ✅ destination database");
|
System.out.println(" ✅ destination database");
|
||||||
}
|
}
|
||||||
@ -276,7 +286,7 @@ public class jrunner {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.out.println("issue retrieving rows from source:");
|
System.out.println("issue retrieving rows from source:");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------build meta---------------------------------------------------------------
|
//---------------------------------------build meta---------------------------------------------------------------
|
||||||
@ -290,7 +300,7 @@ public class jrunner {
|
|||||||
dtn = new String[cols + 1];
|
dtn = new String[cols + 1];
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
for (int i = 1; i <= cols; i++){
|
for (int i = 1; i <= cols; i++){
|
||||||
@ -301,7 +311,7 @@ public class jrunner {
|
|||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
//-------------------------clear the target table if requeted----------------------------------------------------
|
//-------------------------clear the target table if requeted----------------------------------------------------
|
||||||
if (!queryMode && clear) {
|
if (!queryMode && clear) {
|
||||||
@ -314,7 +324,7 @@ public class jrunner {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.out.println(sql);
|
System.out.println(sql);
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (queryMode) {
|
if (queryMode) {
|
||||||
@ -323,7 +333,7 @@ public class jrunner {
|
|||||||
outputQueryResults(rs, cols, dtn, outputFormat);
|
outputQueryResults(rs, cols, dtn, outputFormat);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
} else if (bulk && dcu.toLowerCase().startsWith("jdbc:sqlserver:")) {
|
} else if (bulk && dcu.toLowerCase().startsWith("jdbc:sqlserver:")) {
|
||||||
//-------------------------------bulk copy (SQL Server dest)-------------------------------------------------
|
//-------------------------------bulk copy (SQL Server dest)-------------------------------------------------
|
||||||
@ -347,7 +357,7 @@ public class jrunner {
|
|||||||
System.out.print("\r" + src.rowsWritten());
|
System.out.print("\r" + src.rowsWritten());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
} else if (bulk && dcu.toLowerCase().startsWith("jdbc:postgresql:")) {
|
} else if (bulk && dcu.toLowerCase().startsWith("jdbc:postgresql:")) {
|
||||||
//-------------------------------bulk copy (COPY, Postgres dest)--------------------------------------------
|
//-------------------------------bulk copy (COPY, Postgres dest)--------------------------------------------
|
||||||
@ -389,7 +399,7 @@ public class jrunner {
|
|||||||
System.out.print("\r" + rows);
|
System.out.print("\r" + rows);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("------------row count-------------------------------------");
|
System.out.println("------------row count-------------------------------------");
|
||||||
@ -523,7 +533,7 @@ public class jrunner {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.out.println(sql);
|
System.out.println(sql);
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
sql = "";
|
sql = "";
|
||||||
}
|
}
|
||||||
@ -538,12 +548,12 @@ public class jrunner {
|
|||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.out.println(sql);
|
System.out.println(sql);
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
die();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//System.out.println(sql);
|
//System.out.println(sql);
|
||||||
@ -767,6 +777,17 @@ public class jrunner {
|
|||||||
return value;
|
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) {
|
private static String escapeTSV(String value) {
|
||||||
return value.replaceAll("\t", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
return value.replaceAll("\t", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user