From a61ae3f036bdaada69d6f74271fbfb94e89b63e7 Mon Sep 17 00:00:00 2001 From: Exlll Date: Thu, 16 Oct 2025 22:59:50 +0200 Subject: [PATCH] Don't erase configuration file on YAML-dump failure Fixes #46 --- .../configlib/YamlConfigurationStore.java | 4 +- .../configlib/YamlConfigurationStoreTest.java | 61 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java b/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java index 86307aa..b45070e 100644 --- a/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java +++ b/configlib-yaml/src/main/java/de/exlll/configlib/YamlConfigurationStore.java @@ -73,8 +73,8 @@ public void write(T configuration, OutputStream outputStream) { requireNonNull(configuration, "configuration"); requireNonNull(outputStream, "output stream"); var extractedCommentNodes = extractor.extractCommentNodes(configuration); - var yamlFileWriter = new YamlWriter(outputStream, properties); var dumpedYaml = tryDump(configuration); + var yamlFileWriter = new YamlWriter(outputStream, properties); yamlFileWriter.writeYaml(dumpedYaml, extractedCommentNodes); } @@ -84,8 +84,8 @@ public void save(T configuration, Path configurationFile) { requireNonNull(configurationFile, "configuration file"); tryCreateParentDirectories(configurationFile); var extractedCommentNodes = extractor.extractCommentNodes(configuration); - var yamlFileWriter = new YamlWriter(configurationFile, properties); var dumpedYaml = tryDump(configuration); + var yamlFileWriter = new YamlWriter(configurationFile, properties); yamlFileWriter.writeYaml(dumpedYaml, extractedCommentNodes); } diff --git a/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java b/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java index 79d7661..bbeea38 100644 --- a/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java +++ b/configlib-yaml/src/test/java/de/exlll/configlib/YamlConfigurationStoreTest.java @@ -572,4 +572,65 @@ void tryCreateParentDirectoriesDoesNotThrowIfParentIsNull(boolean createParentDi Path path = fs.getPath("config.yml"); assertDoesNotThrow(() -> store.tryCreateParentDirectories(path)); } + + private record ThrowingWhileSerializingSerializer() + implements Serializer { + + @Override + public String serialize(String element) { + throw new UnsupportedOperationException(element); + } + + @Override + public String deserialize(String element) { + return element; + } + } + + @Configuration + private static final class G { + private String content = "-"; + } + + @Test + void saveDoesNotOverwriteConfigurationFileContentsOnYamlDumpFailure() throws IOException { + YamlConfigurationStore store = new YamlConfigurationStore<>( + G.class, + YamlConfigurationProperties.newBuilder() + .addSerializer(String.class, new ThrowingWhileSerializingSerializer()) + .build() + ); + + String content = "content: abcde"; + Files.writeString(yamlFile, content); + + G config = store.load(yamlFile); + assertThat(config.content, is("abcde")); + assertThrows( + UnsupportedOperationException.class, + () -> store.save(config, yamlFile) + ); + assertThat(readFile(yamlFile), is(content)); + } + + @Test + void writeDoesNotOverwriteStreamContentsOnYamlDumpFailure() { + YamlConfigurationStore store = new YamlConfigurationStore<>( + G.class, + YamlConfigurationProperties.newBuilder() + .addSerializer(String.class, new ThrowingWhileSerializingSerializer()) + .build() + ); + + String content = "content: abcde"; + outputStream.writeBytes(content.getBytes()); + + G config = store.read(inputFromOutput()); + assertThat(config.content, is("abcde")); + assertThrows( + UnsupportedOperationException.class, + () -> store.write(config, outputStream) + ); + assertThat(outputStream.toString(), is(content)); + } }