From f3877e823ee90948d23f5987725e7e3fc84e1ea7 Mon Sep 17 00:00:00 2001 From: Danilo Pianini Date: Tue, 14 Apr 2026 18:18:43 +0200 Subject: [PATCH] fix: throw clear errors when constant instantiation is performed through YAML directly --- .../boundary/loader/SimulationModel.kt | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/alchemist-loading/src/main/kotlin/it/unibo/alchemist/boundary/loader/SimulationModel.kt b/alchemist-loading/src/main/kotlin/it/unibo/alchemist/boundary/loader/SimulationModel.kt index 59b93234fe..6e6645f594 100644 --- a/alchemist-loading/src/main/kotlin/it/unibo/alchemist/boundary/loader/SimulationModel.kt +++ b/alchemist-loading/src/main/kotlin/it/unibo/alchemist/boundary/loader/SimulationModel.kt @@ -382,18 +382,33 @@ internal object SimulationModel { } private fun visitConstant(name: String, context: Context, root: Any?): Result>? { - val constant: Result>? = - when (root) { - is Map<*, *> -> { - visitDependentVariable(name, context, root) - ?.mapCatching { it.getWith(context.constants) } - ?.onFailure { - logger.debug("Evaluation failed at {}, context {}:\n{}", root, context, it.message) - }?.onSuccess { context.registerConstant(name, root, it) } - ?.map { Constant(it) } - } - else -> null + fun unsupportedConstantInstantiation(): Nothing = throw IllegalArgumentException( + """ + Constant creation failed: '$name' with value '$root'. + Direct constant instantiation from YAML is not supported, please consult the Alchemist YAML spec at: + > https://alchemistsimulator.github.io/reference/yaml/index.html#variable + Likely workaround: + ```yaml + $name: + formula: > + $root + ``` + """.trimIndent(), + ) + val constant: Result>? = when (root) { + is Number -> unsupportedConstantInstantiation() + is String -> unsupportedConstantInstantiation() + is Boolean -> unsupportedConstantInstantiation() + is Map<*, *> -> { + visitDependentVariable(name, context, root) + ?.mapCatching { it.getWith(context.constants) } + ?.onFailure { + logger.debug("Evaluation failed at {}, context {}:\n{}", root, context, it.message) + }?.onSuccess { context.registerConstant(name, root, it) } + ?.map { Constant(it) } } + else -> null + } constant?.onSuccess { logger.debug("Variable {}, evaluated from {} as constant, returned {}", name, root, it.value) check(!context.constants.containsKey(name) || context.constants[name] == it.value) {