diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/classgen/roaster/RoasterCodeGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/classgen/roaster/RoasterCodeGenerator.java index a718849a..959800e3 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/classgen/roaster/RoasterCodeGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/classgen/roaster/RoasterCodeGenerator.java @@ -102,7 +102,15 @@ public void generateClass(GenerationTargetClassDto classDef) throws BuilderExcep logger.debugStartOperation( "Code generation for class: %s", classDef.getTypeName().getClassName()); - String sourceCode = createClassSource(classDef); + String sourceCode; + try { + sourceCode = createClassSource(classDef); + } catch (RuntimeException ex) { + // Rendering failures (e.g. RoasterMapperException) are RuntimeExceptions. Convert them into + // a BuilderException so callers can isolate the failure to this single class and keep + // generating the remaining builders instead of aborting the whole processing round. + throw new BuilderException(null, ex); + } writeClassToFile(sourceCode, classDef); logger.debugEndOperation( diff --git a/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java b/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java new file mode 100644 index 00000000..63eac689 --- /dev/null +++ b/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java @@ -0,0 +1,159 @@ +/* + * MIT License + * + * Copyright (c) 2026 Andreas Igel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.javahelpers.simple.builders.processor; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Collections; +import java.util.Locale; +import java.util.Map; +import javax.annotation.processing.Filer; +import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic; +import org.javahelpers.simple.builders.core.enums.AccessModifier; +import org.javahelpers.simple.builders.processor.classgen.roaster.RoasterCodeGenerator; +import org.javahelpers.simple.builders.processor.classgen.roaster.exceptions.RoasterMapperException; +import org.javahelpers.simple.builders.processor.exceptions.BuilderException; +import org.javahelpers.simple.builders.processor.model.core.GenerationTargetClassDto; +import org.javahelpers.simple.builders.processor.model.method.ConstructorDto; +import org.javahelpers.simple.builders.processor.model.method.MethodCodeDto; +import org.javahelpers.simple.builders.processor.model.method.MethodCodePlaceholder; +import org.javahelpers.simple.builders.processor.model.type.TypeName; +import org.javahelpers.simple.builders.processor.processing.ProcessingLogger; +import org.junit.jupiter.api.Test; + +/** + * Regression tests for {@link RoasterCodeGenerator} error-handling robustness. + * + *
Rendering failures surface as {@link RoasterMapperException}, which extends {@link
+ * RuntimeException}. These must be converted into the checked {@link BuilderException} so that the
+ * per-builder resilience loops in {@code BuilderProcessor} can isolate the failure to the offending
+ * class and continue generating the remaining builders instead of aborting the whole round.
+ */
+class RoasterCodeGeneratorResilienceTest {
+
+ /** Placeholder subtype the mapper does not know how to render, forcing a mapping failure. */
+ private static final class UnsupportedPlaceholder extends MethodCodePlaceholder