diff --git a/server/src/main/java/org/opensearch/bootstrap/OpenSearch.java b/server/src/main/java/org/opensearch/bootstrap/OpenSearch.java index 7b011b5828428..8e5f78642dd07 100644 --- a/server/src/main/java/org/opensearch/bootstrap/OpenSearch.java +++ b/server/src/main/java/org/opensearch/bootstrap/OpenSearch.java @@ -89,6 +89,7 @@ public static void main(final String[] args) throws Exception { LogConfigurator.registerErrorListener(); final OpenSearch opensearch = new OpenSearch(); int status = main(args, opensearch, Terminal.DEFAULT); + if (status != ExitCodes.OK) { final String basePath = System.getProperty("opensearch.logs.base_path"); // It's possible to fail before logging has been configured, in which case there's no point @@ -122,7 +123,14 @@ private static void overrideDnsCachePolicyProperties() { } static int main(final String[] args, final OpenSearch opensearch, final Terminal terminal) throws Exception { - return opensearch.main(args, terminal); + try { + return opensearch.main(args, terminal); + } catch (StartupException e) { + // StartupException has custom printStackTrace formatting (truncates guice frames, etc.). + // Catch it here so the process exits rather than hanging, while preserving that output. + e.printStackTrace(terminal.getErrorWriter()); + return ExitCodes.CODE_ERROR; + } } @Override diff --git a/server/src/test/java/org/opensearch/bootstrap/OpenSearchCliTests.java b/server/src/test/java/org/opensearch/bootstrap/OpenSearchCliTests.java index f4d8e055f0795..481d2c14339bb 100644 --- a/server/src/test/java/org/opensearch/bootstrap/OpenSearchCliTests.java +++ b/server/src/test/java/org/opensearch/bootstrap/OpenSearchCliTests.java @@ -226,4 +226,18 @@ public void testUnknownOption() throws Exception { ); } + public void testStartupExceptionExitsWithCodeError() throws Exception { + // StartupException is caught in the 3-arg main(), which prints it via its custom formatter + // and returns CODE_ERROR so that the 1-arg main() calls exit(CODE_ERROR). + final RuntimeException cause = new RuntimeException("dummy startup failure"); + runTest( + ExitCodes.CODE_ERROR, + true, + (output, error) -> assertThat(error, containsString(cause.getMessage())), + (foreground, pidFile, quiet, env) -> { + throw new StartupException(cause); + } + ); + } + }