diff --git a/core/src/main/java/org/spongepowered/configurate/ScopedConfigurationNode.java b/core/src/main/java/org/spongepowered/configurate/ScopedConfigurationNode.java index 4f592ff9c..9c62aec0d 100644 --- a/core/src/main/java/org/spongepowered/configurate/ScopedConfigurationNode.java +++ b/core/src/main/java/org/spongepowered/configurate/ScopedConfigurationNode.java @@ -16,6 +16,7 @@ */ package org.spongepowered.configurate; +import io.leangen.geantyref.GenericTypeReflector; import io.leangen.geantyref.TypeToken; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.configurate.serialize.SerializationException; @@ -104,6 +105,11 @@ default N set(Type type, @Nullable Object value) throws SerializationException { if (value == null) { return set(null); } + final Class erasedType = GenericTypeReflector.erase(type); + if (!erasedType.isInstance(value)) { + throw new SerializationException(this, type, "Got a value of unexpected type " + + value.getClass().getName() + ", when the value should be an instance of " + erasedType.getSimpleName()); + } final @Nullable TypeSerializer serial = options().serializers().get(type); if (serial != null) { @@ -111,7 +117,7 @@ default N set(Type type, @Nullable Object value) throws SerializationException { } else if (options().acceptsType(value.getClass())) { raw(value); // Just write if no applicable serializer exists? } else { - throw new SerializationException("No serializer available for type " + type); + throw new SerializationException(this, type, "No serializer available for type " + type); } return self(); } diff --git a/core/src/test/java/org/spongepowered/configurate/AbstractConfigurationNodeTest.java b/core/src/test/java/org/spongepowered/configurate/AbstractConfigurationNodeTest.java index 6cd76431f..68faa2c0d 100644 --- a/core/src/test/java/org/spongepowered/configurate/AbstractConfigurationNodeTest.java +++ b/core/src/test/java/org/spongepowered/configurate/AbstractConfigurationNodeTest.java @@ -487,4 +487,13 @@ void testMergeToVirtualNode() throws SerializationException { assertFalse(target.virtual()); } + @Test + void testSetValueOfInvalidType() { + final BasicConfigurationNode root = BasicConfigurationNode.root(ConfigurationOptions.defaults() + .nativeTypes(UnmodifiableCollections.toSet(String.class))); + + assertTrue(assertThrows(SerializationException.class, () -> root.set(Integer.class, "hello")) + .getMessage().contains("Got a value of unexpected type")); + } + }