From 3307bc5b1dff40d802211f91809623d830444237 Mon Sep 17 00:00:00 2001 From: Fritx22 <57330546+Fritx22@users.noreply.github.com> Date: Sat, 11 Jul 2026 16:24:58 -0300 Subject: [PATCH] fix(core): Wildcard transformation exceptions * Fix SingleConfigurationTransformation not throwing ConfigurateException exceptions when applying an action to a wildcard path, unlike when applying it to paths without wildcard * Add tests covering all ConfigurateException exceptions thrown while processing a transformation --- .../SingleConfigurationTransformation.java | 5 + .../ConfigurationTransformationTest.java | 133 ++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/core/src/main/java/org/spongepowered/configurate/transformation/SingleConfigurationTransformation.java b/core/src/main/java/org/spongepowered/configurate/transformation/SingleConfigurationTransformation.java index 6d66da85a..aeb167c1e 100644 --- a/core/src/main/java/org/spongepowered/configurate/transformation/SingleConfigurationTransformation.java +++ b/core/src/main/java/org/spongepowered/configurate/transformation/SingleConfigurationTransformation.java @@ -108,6 +108,11 @@ private void applySingleAction(final ConfigurationNode start, final Object[] pat // No children return; } + + if (thrown != null) { + throw thrown; + } + return; } else { node = node.node(path[i]); diff --git a/core/src/test/java/org/spongepowered/configurate/transformation/ConfigurationTransformationTest.java b/core/src/test/java/org/spongepowered/configurate/transformation/ConfigurationTransformationTest.java index ba3d9fab1..910d29fd2 100644 --- a/core/src/test/java/org/spongepowered/configurate/transformation/ConfigurationTransformationTest.java +++ b/core/src/test/java/org/spongepowered/configurate/transformation/ConfigurationTransformationTest.java @@ -18,6 +18,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.spongepowered.configurate.NodePath.path; @@ -264,4 +265,136 @@ void testVersionedTransformationMoveChildToRoot() throws ConfigurateException { assertEquals(transformed, original); } + private void assertConfigurateEx(final ConfigurationNode root, final ConfigurationTransformation transformation, final int suppressedAmount) { + final ConfigurateException ex = assertThrows(ConfigurateException.class, () -> transformation.apply(root)); + assertEquals(ex.rawMessage(), "test exception"); + + final Throwable[] suppressedArr = ex.getSuppressed(); + assertEquals(suppressedArr.length, suppressedAmount); + + for (final Throwable throwable : suppressedArr) { + assertEquals(throwable.getClass(), ConfigurateException.class); + final ConfigurateException suppressedEx = (ConfigurateException) throwable; + assertEquals(suppressedEx.rawMessage(), "test suppressed exception"); + } + } + + @Test + void testSingleTransformationThrowsConfigurateException() throws ConfigurateException { + final BasicConfigurationNode root = BasicConfigurationNode.root(b -> { + b.node("test-key").raw("test-value"); + b.node("zzz").raw("zzz"); + b.node("zzzz").raw("zzzz"); + }); + + final ConfigurationTransformation transformation = ConfigurationTransformation.builder() + .addAction(path("test-key"), (path, value) -> { + throw new ConfigurateException("test exception"); + }) + .addAction(path("zzz"), (path, value) -> { + throw new ConfigurateException("test suppressed exception"); + }) + .addAction(path("zzzz"), (path, value) -> { + throw new ConfigurateException("test suppressed exception"); + }) + .build(); + + this.assertConfigurateEx(root, transformation, 2); + } + + private ConfigurationTransformation createWildcardTransformation() { + return ConfigurationTransformation.builder() + .addAction(path("test", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { + if (value.getString().equals("value1")) { + throw new ConfigurateException("test exception"); + } else { + throw new ConfigurateException("test suppressed exception"); + } + }) + .build(); + } + + @Test + void testSingleTransformationWildcardMapThrowsConfigurateException() throws ConfigurateException { + final BasicConfigurationNode root = BasicConfigurationNode.root(b -> { + b.node("test").act(t -> { + t.node("child1").raw("value1"); + t.node("child2").raw("value2"); + t.node("child3").raw("value3"); + }); + }); + + final ConfigurationTransformation transformation = this.createWildcardTransformation(); + + this.assertConfigurateEx(root, transformation, 2); + } + + @Test + void testSingleTransformationWildcardListThrowsConfigurateException() throws ConfigurateException { + final BasicConfigurationNode root = BasicConfigurationNode.root(b -> { + b.node("test").setList(String.class, Arrays.asList("value1", "value2", "value3")); + }); + + final ConfigurationTransformation transformation = this.createWildcardTransformation(); + + this.assertConfigurateEx(root, transformation, 2); + } + + @Test + void testVersionedTransformationThrowsConfigurateException() throws ConfigurateException { + final BasicConfigurationNode root = BasicConfigurationNode.root(b -> { + b.node("test").raw("test value"); + b.node("zzz").raw("zzz"); + b.node("zzzz").raw("zzzz"); + }); + + final ConfigurationTransformation.Versioned transformation = ConfigurationTransformation.versionedBuilder() + .makeVersion(0, (version) -> { + version.addAction(path("test"), (path, value) -> null); + }) + .makeVersion(1, (version) -> { + version.addAction(path("test"), (path, value) -> { + throw new ConfigurateException("test exception"); + }); + version.addAction(path("zzz"), (path, value) -> { + throw new ConfigurateException("test suppressed exception"); + }); + version.addAction(path("zzzz"), (path, value) -> { + throw new ConfigurateException("test suppressed exception"); + }); + }) + .build(); + + this.assertConfigurateEx(root, transformation, 2); + } + + @Test + void testChainedTransformationThrowsConfigurateException() throws ConfigurateException { + final BasicConfigurationNode root = BasicConfigurationNode.root(b -> { + b.node("test").raw("test"); + b.node("zzz").raw("zzz"); + b.node("zzzz").raw("zzzz"); + }); + + final ConfigurationTransformation transformation = ConfigurationTransformation.chain( + ConfigurationTransformation.builder() + .addAction(path("test"), (path, value) -> { + throw new ConfigurateException("test exception"); + }) + .build(), + ConfigurationTransformation.builder() + .addAction(path("zzz"), (path, value) -> { + throw new ConfigurateException("test suppressed exception"); + }) + .build(), + ConfigurationTransformation.builder() + .addAction(path("zzzz"), (path, value) -> { + throw new ConfigurateException("test suppressed exception"); + }) + .build() + ); + + this.assertConfigurateEx(root, transformation, 2); + } + }