From bd1d102556fd3b157bd85587bf01e07e8ef7d9ba Mon Sep 17 00:00:00 2001 From: Nate Bradac Date: Mon, 29 Jun 2026 13:56:02 -0500 Subject: [PATCH 1/2] catch validation errors and return -1 instead of propagating an exception --- .../java/uk/co/real_logic/sbe/SbeTool.java | 24 +++++- .../uk/co/real_logic/sbe/SbeToolTest.java | 85 +++++++++++++++++++ 2 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 sbe-tool/src/test/java/uk/co/real_logic/sbe/SbeToolTest.java diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java index 552a9656ab..711f7dd2a2 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java @@ -32,6 +32,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.function.IntConsumer; /** * A tool for running the SBE parser, validator, and code generator. @@ -255,11 +256,17 @@ public class SbeTool * @throws Exception if an error occurs during process of the message schema. */ public static void main(final String[] args) throws Exception + { + run(args, System::exit); + } + + static void run(final String[] args, final IntConsumer exitHandler) throws Exception { if (args.length == 0) { System.err.format("Usage: %s ...%n", SbeTool.class.getName()); - System.exit(-1); + exitHandler.accept(-1); + return; } for (final String fileName : args) @@ -273,7 +280,18 @@ public static void main(final String[] args) throws Exception validateAgainstSchema(fileName, xsdFilename); } - final MessageSchema schema = parseSchema(fileName); + final MessageSchema schema; + try + { + schema = parseSchema(fileName); + } + catch (final IllegalStateException | IllegalArgumentException ex) + { + System.err.println(ex.getMessage()); + exitHandler.accept(-1); + return; + } + final SchemaTransformer transformer = new SchemaTransformerFactory( System.getProperty(SCHEMA_TRANSFORM_VERSION)); ir = new IrGenerator().generate(transformer.transform(schema), System.getProperty(TARGET_NAMESPACE)); @@ -288,7 +306,7 @@ else if (fileName.endsWith(".sbeir")) else { System.err.println("Input file format not supported: " + fileName); - System.exit(-1); + exitHandler.accept(-1); return; } diff --git a/sbe-tool/src/test/java/uk/co/real_logic/sbe/SbeToolTest.java b/sbe-tool/src/test/java/uk/co/real_logic/sbe/SbeToolTest.java new file mode 100644 index 0000000000..35ec33d672 --- /dev/null +++ b/sbe-tool/src/test/java/uk/co/real_logic/sbe/SbeToolTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2013-2025 Real Logic Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package uk.co.real_logic.sbe; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; + +import java.net.URL; +import java.nio.file.Paths; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SbeToolTest +{ + @AfterEach + void restoreSystemProperties() + { + System.clearProperty(SbeTool.VALIDATION_STOP_ON_ERROR); + System.clearProperty(SbeTool.VALIDATION_WARNINGS_FATAL); + System.clearProperty(SbeTool.VALIDATION_SUPPRESS_OUTPUT); + System.clearProperty(SbeTool.GENERATE_STUBS); + } + + @Test + void shouldExitOnValidationErrorsWhenStopOnError() throws Exception + { + System.setProperty(SbeTool.VALIDATION_STOP_ON_ERROR, "true"); + System.setProperty(SbeTool.VALIDATION_SUPPRESS_OUTPUT, "true"); + System.setProperty(SbeTool.GENERATE_STUBS, "false"); + + final AtomicInteger capturedCode = new AtomicInteger(0); + SbeTool.run(new String[]{ schemaPath("error-handler-types-schema.xml") }, capturedCode::set); + + assertEquals(-1, capturedCode.get()); + } + + @Test + void shouldExitOnValidationErrorsWithoutStopOnError() throws Exception + { + System.setProperty(SbeTool.VALIDATION_SUPPRESS_OUTPUT, "true"); + System.setProperty(SbeTool.GENERATE_STUBS, "false"); + + final AtomicInteger capturedCode = new AtomicInteger(0); + SbeTool.run(new String[]{ schemaPath("error-handler-types-schema.xml") }, capturedCode::set); + + assertEquals(-1, capturedCode.get()); + } + + @Test + void shouldExitOnWarningsWhenWarningsFatal() throws Exception + { + System.setProperty(SbeTool.VALIDATION_WARNINGS_FATAL, "true"); + System.setProperty(SbeTool.VALIDATION_SUPPRESS_OUTPUT, "true"); + System.setProperty(SbeTool.GENERATE_STUBS, "false"); + + final AtomicInteger capturedCode = new AtomicInteger(0); + SbeTool.run(new String[]{ schemaPath("error-handler-types-dup-schema.xml") }, capturedCode::set); + + assertEquals(-1, capturedCode.get()); + } + + private static String schemaPath(final String resourceName) throws Exception + { + final URL url = Tests.class.getClassLoader().getResource(resourceName); + if (url == null) + { + throw new IllegalArgumentException("resource not found: " + resourceName); + } + return Paths.get(url.toURI()).toString(); + } +} From 5722ec4498dcc56876ce6390914f0b9798983b87 Mon Sep 17 00:00:00 2001 From: Nate Bradac Date: Mon, 6 Jul 2026 07:46:59 -0500 Subject: [PATCH 2/2] use generic Exception in catch block --- sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java b/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java index 711f7dd2a2..6febe4dba8 100644 --- a/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java +++ b/sbe-tool/src/main/java/uk/co/real_logic/sbe/SbeTool.java @@ -285,7 +285,7 @@ static void run(final String[] args, final IntConsumer exitHandler) throws Excep { schema = parseSchema(fileName); } - catch (final IllegalStateException | IllegalArgumentException ex) + catch (final Exception ex) { System.err.println(ex.getMessage()); exitHandler.accept(-1);