Skip to content

Commit f4635ba

Browse files
authored
Collect all validation error codes (#1534)
This commit collects all validation error codes into ValidationErrorCodes.kt. Closes: gh-1533 Signed-off-by: Arjen Poutsma <poutsma@mac.com>
1 parent 738f5bc commit f4635ba

File tree

4 files changed

+58
-8
lines changed

4 files changed

+58
-8
lines changed

embabel-agent-api/src/main/kotlin/com/embabel/agent/spi/validation/DefaultAgentStructureValidator.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.embabel.agent.api.annotation.Agent
2020
import com.embabel.agent.api.annotation.Condition
2121
import com.embabel.agent.core.AgentScope
2222
import com.embabel.common.core.validation.ValidationError
23+
import com.embabel.common.core.validation.ValidationErrorCodes
2324
import com.embabel.common.core.validation.ValidationLocation
2425
import com.embabel.common.core.validation.ValidationResult
2526
import com.embabel.common.core.validation.ValidationSeverity
@@ -60,7 +61,7 @@ class DefaultAgentStructureValidator(
6061

6162
if (actionMethods.isEmpty() && conditionMethods.isEmpty() && !hasGoals) {
6263
val error = ValidationError(
63-
code = "EMPTY_AGENT_STRUCTURE",
64+
code = ValidationErrorCodes.EMPTY_AGENT_STRUCTURE,
6465
message = "Agent class '${clazz.name}' has no @Action or @Condition methods and no goals defined. This agent will NOT be registered!",
6566
severity = ValidationSeverity.ERROR,
6667
location = ValidationLocation(
@@ -82,7 +83,7 @@ class DefaultAgentStructureValidator(
8283
if (agentScope.actions.isEmpty() && agentScope.conditions.isEmpty() && agentScope.goals.isEmpty()) {
8384
errors.add(
8485
ValidationError(
85-
code = "EMPTY_AGENT_STRUCTURE",
86+
code = ValidationErrorCodes.EMPTY_AGENT_STRUCTURE,
8687
message = "Agent '${agentScope.name}' has no actions, conditions, or goals defined",
8788
severity = ValidationSeverity.ERROR,
8889
location = ValidationLocation(
@@ -99,7 +100,7 @@ class DefaultAgentStructureValidator(
99100
if (agentScope.goals.isEmpty()) {
100101
errors.add(
101102
ValidationError(
102-
code = "MISSING_GOALS",
103+
code = ValidationErrorCodes.MISSING_GOALS,
103104
message = "Agent '${agentScope.name}' must have at least one goal defined",
104105
severity = ValidationSeverity.ERROR,
105106
location = ValidationLocation(
@@ -116,7 +117,7 @@ class DefaultAgentStructureValidator(
116117
agentScope.actions.groupBy { it.name }.filter { it.value.size > 1 }.forEach { (name, _) ->
117118
errors.add(
118119
ValidationError(
119-
code = "DUPLICATE_ACTION_NAME",
120+
code = ValidationErrorCodes.DUPLICATE_ACTION_NAME,
120121
message = "Agent '${agentScope.name}' has more than one action named '$name'",
121122
severity = ValidationSeverity.ERROR,
122123
location = ValidationLocation(
@@ -141,7 +142,7 @@ class DefaultAgentStructureValidator(
141142
if (preconditionsWithMultipleParams) {
142143
errors.add(
143144
ValidationError(
144-
code = "INVALID_ACTION_SIGNATURE",
145+
code = ValidationErrorCodes.INVALID_ACTION_SIGNATURE,
145146
message = "Action '${action.name}' has preconditions with multiple parameters",
146147
severity = ValidationSeverity.ERROR,
147148
location = ValidationLocation(
@@ -163,7 +164,7 @@ class DefaultAgentStructureValidator(
163164
if (method?.parameterCount ?: 0 > 1) {
164165
errors.add(
165166
ValidationError(
166-
code = "INVALID_CONDITION_SIGNATURE",
167+
code = ValidationErrorCodes.INVALID_CONDITION_SIGNATURE,
167168
message = "Condition '${condition.name}' must have at most one parameter",
168169
severity = ValidationSeverity.ERROR,
169170
location = ValidationLocation(

embabel-agent-api/src/main/kotlin/com/embabel/agent/spi/validation/GoapPathToCompletionValidator.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package com.embabel.agent.spi.validation
1818
import com.embabel.agent.core.AgentScope
1919
import com.embabel.agent.core.support.Rerun.HAS_RUN_CONDITION_PREFIX
2020
import com.embabel.common.core.validation.ValidationError
21+
import com.embabel.common.core.validation.ValidationErrorCodes
2122
import com.embabel.common.core.validation.ValidationLocation
2223
import com.embabel.common.core.validation.ValidationResult
2324
import com.embabel.common.core.validation.ValidationSeverity
@@ -47,7 +48,13 @@ class GoapPathToCompletionValidator : PathToCompletionAgentValidator {
4748
}
4849

4950
if (agentScope.actions.isEmpty()) {
50-
errors.add(error("NO_ACTIONS_TO_GOALS", "Agent '${agentScope.name}' has no actions.", agentScope))
51+
errors.add(
52+
error(
53+
ValidationErrorCodes.NO_ACTIONS_TO_GOALS,
54+
"Agent '${agentScope.name}' has no actions.",
55+
agentScope
56+
)
57+
)
5158
return ValidationResult(false, errors)
5259
}
5360

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2024-2026 Embabel Pty Ltd.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.embabel.common.core.validation
17+
18+
/**
19+
* Well-known error codes used in [ValidationError] instances produced by the built-in validators.
20+
*/
21+
class ValidationErrorCodes {
22+
companion object {
23+
/** Agent class has no @Action or @Condition methods and no goals defined. */
24+
const val EMPTY_AGENT_STRUCTURE = "EMPTY_AGENT_STRUCTURE"
25+
26+
/** Agent has no goals, so it can never be considered complete. */
27+
const val MISSING_GOALS = "MISSING_GOALS"
28+
29+
/** Two or more actions in the same agent share the same name, typically caused by overloaded @Action methods. */
30+
const val DUPLICATE_ACTION_NAME = "DUPLICATE_ACTION_NAME"
31+
32+
/** An action has preconditions whose backing methods take more than one parameter. */
33+
const val INVALID_ACTION_SIGNATURE = "INVALID_ACTION_SIGNATURE"
34+
35+
/** A condition method takes more than one parameter. */
36+
const val INVALID_CONDITION_SIGNATURE = "INVALID_CONDITION_SIGNATURE"
37+
38+
/** Agent has goals but no actions, so no plan can ever reach them. */
39+
const val NO_ACTIONS_TO_GOALS = "NO_ACTIONS_TO_GOALS"
40+
}
41+
}

embabel-agent-api/src/test/kotlin/com/embabel/agent/validation/DefaultAgentStructureValidatorTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.embabel.agent.api.annotation.support.AgentMetadataReader
1919
import com.embabel.agent.api.annotation.support.AgentWithDuplicateActionNames
2020
import com.embabel.agent.api.dsl.evenMoreEvilWizard
2121
import com.embabel.agent.spi.validation.DefaultAgentStructureValidator
22+
import com.embabel.common.core.validation.ValidationErrorCodes
2223
import org.junit.jupiter.api.Assertions.assertEquals
2324
import org.junit.jupiter.api.Assertions.assertTrue
2425
import org.junit.jupiter.api.Nested
@@ -59,7 +60,7 @@ class DefaultAgentStructureValidatorTest {
5960
val result = validator().validate(agentScope)
6061

6162
assertTrue(
62-
result.errors.any { it.code == "DUPLICATE_ACTION_NAME" },
63+
result.errors.any { it.code == ValidationErrorCodes.DUPLICATE_ACTION_NAME },
6364
"Expected a DUPLICATE_ACTION_NAME validation error, but got: ${result.errors}",
6465
)
6566
}

0 commit comments

Comments
 (0)