Skip to content

Commit 5102355

Browse files
authored
Merge pull request #785 from bci-oss/784-introduce-systematic-error-codes
Introduce error codes core
2 parents 25022f9 + eb446d2 commit 5102355

File tree

8 files changed

+442
-3
lines changed

8 files changed

+442
-3
lines changed

core/esmf-aspect-model-validator/src/main/java/org/eclipse/esmf/aspectmodel/validation/services/DetailedViolationFormatter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ private String formatViolation( final Violation violation, final Supplier<String
141141
builder.append( String.format( " - %s%n", fix.description() ) );
142142
}
143143
}
144+
// Add documentation link
145+
builder.append( " documentation: https://eclipse-esmf.github.io/esmf-developer-guide/tooling-guide/error-codes.html"
146+
+ violation.errorCode().toLowerCase().replace( "_", "-" ) );
144147
builder.append( indent( additionalAttributesSupplier.get(), 2 ) );
145148
if ( violation.context() != null ) {
146149
builder.append( String.format( " caused-by-shape:%n" ) );

core/esmf-aspect-model-validator/src/main/java/org/eclipse/esmf/aspectmodel/validation/services/ViolationFormatter.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public class ViolationFormatter implements Function<List<Violation>, String>, Vi
4242
protected final String additionalHints;
4343
protected final RustLikeFormatter formatter;
4444

45+
private static final String ERROR_CODES_DOC_LINK = "https://eclipse-esmf.github.io/esmf-developer-guide/tooling-guide/error-codes.html";
46+
private static final String ERROR_CODES_DOC_STRING = "For more information, see: documentation: " + ERROR_CODES_DOC_LINK;
47+
4548
public ViolationFormatter( final String additionalHints ) {
4649
this( new PlainTextFormatter(), additionalHints );
4750
}
@@ -84,11 +87,17 @@ public String apply( final List<Violation> violations ) {
8487
final List<Violation> elementViolations = entry.getValue();
8588
builder.append( String.format( "> %s :%n", textFormatter.formatName( elementName ) ) );
8689
for ( final Violation violation : elementViolations ) {
90+
// Include error code in the violation message
91+
final String errorCode = violation.errorCode();
92+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
8793
builder.append( indent( violation.accept( this ), 2 ) ).append( System.lineSeparator() );
8894
for ( final Fix possibleFix : violation.fixes() ) {
8995
builder.append( " > Possible fix: " )
9096
.append( possibleFix.description() );
9197
}
98+
// Add documentation link
99+
builder.append( String.format( ERROR_CODES_DOC_STRING + "#%s%n",
100+
errorCode.toLowerCase().replace( "_", "-" ) ) );
92101
builder.append( System.lineSeparator() );
93102
}
94103
builder.append( System.lineSeparator() );
@@ -98,10 +107,20 @@ public String apply( final List<Violation> violations ) {
98107
if ( violation instanceof final ProcessingViolation processingViolation ) {
99108
builder.append( processingViolation.accept( this ) );
100109
} else if ( violation.violationSpecificMessage() == null || violation.violationSpecificMessage().equals( violation.message() ) ) {
101-
builder.append( String.format( "> %s%n", violation.message() ) );
110+
final String errorCode = violation.errorCode();
111+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
112+
builder.append( String.format( "> %s%n", enhancedMessage ) );
113+
// Add documentation link for context-free violations
114+
builder.append( ERROR_CODES_DOC_STRING
115+
+ errorCode.toLowerCase().replace( "_", "-" ) );
102116
} else {
103-
builder.append( String.format( "> %s: %n", violation.message() ) );
117+
final String errorCode = violation.errorCode();
118+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
119+
builder.append( String.format( "> %s: %n", enhancedMessage ) );
104120
builder.append( indent( violation.accept( this ), 2 ) ).append( System.lineSeparator() );
121+
// Add documentation link
122+
builder.append( ERROR_CODES_DOC_STRING
123+
+ errorCode.toLowerCase().replace( "_", "-" ) );
105124
}
106125
builder.append( System.lineSeparator() );
107126
}
@@ -111,7 +130,9 @@ public String apply( final List<Violation> violations ) {
111130

112131
@Override
113132
public String visit( final Violation violation ) {
114-
return formatter.constructDetailedMessage( violation.highlight(), violation.message(), violation.context().element().getModel() );
133+
final String errorCode = violation.errorCode();
134+
final String enhancedMessage = String.format( "[%s] %s", errorCode, violation.message() );
135+
return formatter.constructDetailedMessage( violation.highlight(), enhancedMessage, violation.context().element().getModel() );
115136
}
116137

117138
@Override
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for additional
5+
* information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
package examples;
15+
16+
// tag::imports[]
17+
import java.util.List;
18+
import java.util.Map;
19+
import java.util.stream.Collectors;
20+
21+
import org.eclipse.esmf.aspectmodel.shacl.violation.DatatypeViolation;
22+
import org.eclipse.esmf.aspectmodel.shacl.violation.MaxCountViolation;
23+
import org.eclipse.esmf.aspectmodel.shacl.violation.Violation;
24+
// end::imports[]
25+
26+
public class CustomViolationFormatter implements Violation.Visitor<String> {
27+
28+
// tag::custom-formatter[]
29+
// Implement other visitor methods for different violation types
30+
@Override
31+
public String visit(Violation violation) {
32+
// Generic fallback for unhandled violation types
33+
return String.format("Validation error: %s", violation.message());
34+
}
35+
// end::custom-formatter[]
36+
37+
// tag::error-aggregation[]
38+
public void aggregateErrors(List<Violation> violations) {
39+
// Group violations by error code for batch processing
40+
Map<String, List<Violation>> errorsByCode = violations.stream()
41+
.collect(Collectors.groupingBy(Violation::errorCode));
42+
43+
// Handle each error type separately
44+
List<Violation> dataTypeErrors = errorsByCode.get("ERR_TYPE");
45+
List<Violation> cardinalityErrors = errorsByCode.get("ERR_MAX_COUNT");
46+
47+
// Process each error type with specific handling logic
48+
if (dataTypeErrors != null && !dataTypeErrors.isEmpty()) {
49+
System.out.println("Found " + dataTypeErrors.size() + " data type errors");
50+
// Handle data type errors...
51+
}
52+
53+
if (cardinalityErrors != null && !cardinalityErrors.isEmpty()) {
54+
System.out.println("Found " + cardinalityErrors.size() + " cardinality errors");
55+
// Handle cardinality errors...
56+
}
57+
}
58+
// end::error-aggregation[]
59+
}

documentation/developer-guide/modules/tooling-guide/examples/ValidateAspectModel.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.util.List;
1919

2020
import org.eclipse.esmf.aspectmodel.loader.AspectModelLoader;
21+
import org.eclipse.esmf.aspectmodel.shacl.fix.Fix;
22+
import org.eclipse.esmf.aspectmodel.shacl.violation.EvaluationContext;
2123
import org.eclipse.esmf.aspectmodel.shacl.violation.Violation;
2224
import org.eclipse.esmf.aspectmodel.validation.services.AspectModelValidator;
2325
import org.eclipse.esmf.aspectmodel.validation.services.DetailedViolationFormatter;
@@ -38,11 +40,20 @@ public void validate() {
3840
new File( "aspect-models/org.eclipse.esmf.examples.movement/1.0.0/Movement.ttl" ) );
3941
// tag::validate[]
4042

43+
// tag::violations[]
4144
final List<Violation> violations = new AspectModelValidator().validateModel( aspectModel );
4245
if ( violations.isEmpty() ) {
4346
// Aspect Model is valid!
4447
return;
48+
} else {
49+
for (Violation violation : violations) {
50+
String errorCode = violation.errorCode();
51+
String message = violation.message();
52+
EvaluationContext context = violation.context();
53+
List<Fix> fixes = violation.fixes();
54+
}
4555
}
56+
// end::violations[]
4657

4758
final String validationReport = new ViolationFormatter().apply( violations ); // <1>
4859
final String detailedReport = new DetailedViolationFormatter().apply( violations );
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
* xref:samm-cli.adoc[SAMM CLI]
22
* xref:java-aspect-tooling.adoc[Java APIs for Aspect Models]
33
* xref:maven-plugin.adoc[Maven Plugin]
4+
* xref:error-codes.adoc[Error Codes and Validation Results]
5+
* xref:best-practices.adoc[Best Practices]
46
* xref:bamm-migration.adoc[Migration from BAMM]
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
:page-partial:
2+
3+
[[best-practices]]
4+
= Best Practices
5+
6+
This guide provides best practices for developing Aspect Models and handling validation errors effectively.
7+
8+
[[analyzing-modeling-errors]]
9+
== Analyzing Modeling Errors
10+
11+
When working with ESMF SDK validation results, follow these practices to efficiently identify and resolve modeling issues.
12+
13+
=== Model Development
14+
15+
1. **Validate Early**: Run validation frequently during model development
16+
2. **Use Detailed Output**: Enable detailed error reporting for comprehensive feedback
17+
3. **Address Errors Systematically**: Start with meta-violations before fixing constraint violations
18+
4. **Test Edge Cases**: Verify models with boundary values and optional properties
19+
20+
=== Error Handling
21+
22+
1. **Programmatic Handling**: Use the visitor pattern for type-safe error handling
23+
2. **User-Friendly Messages**: Transform technical errors into user-friendly guidance
24+
3. **Logging**: Log error codes and context for troubleshooting
25+
4. **Documentation**: Link to error code documentation in error messages where appropriate
26+
27+

0 commit comments

Comments
 (0)