Error handling for Spring Boot APIs — @ControllerAdvice, structured error
84
75%
Does it follow best practices?
Impact
99%
1.76xAverage score across 5 eval scenarios
Passed
No known issues
{
"context": "Tests whether the agent proactively adds production-grade error handling (global @RestControllerAdvice, custom exception hierarchy, structured error responses, no stack trace leaks, validation with @Valid, DataIntegrityViolation handling, MDC logging) when building a Spring Boot CRUD API that does not mention error handling in the requirements.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Global exception handler with @RestControllerAdvice",
"description": "A centralized exception handler class annotated with @RestControllerAdvice or @ControllerAdvice is defined, containing multiple @ExceptionHandler methods",
"max_score": 15
},
{
"name": "Custom exception hierarchy",
"description": "Custom exception classes are defined (e.g., ResourceNotFoundException, BusinessRuleException) with HTTP status code mapping, rather than throwing raw RuntimeException or using ResponseStatusException throughout",
"max_score": 12
},
{
"name": "Consistent structured error response format",
"description": "Error responses use a consistent object shape with at least a code/type field and a message field (e.g., { error: { code, message } }). The format is the same across all error cases -- not a mix of different response shapes",
"max_score": 12
},
{
"name": "Validation error handler with field details",
"description": "MethodArgumentNotValidException is handled in the global exception handler, extracting field-level errors and returning them in a structured format with field names and messages",
"max_score": 12
},
{
"name": "No stack trace leaks",
"description": "The catch-all Exception handler returns a generic safe message (e.g., 'An unexpected error occurred') without stack traces, raw library messages, or internal details. Ideally server.error.include-stacktrace=never is configured",
"max_score": 12
},
{
"name": "Bean validation with @Valid",
"description": "@Valid is used on @RequestBody parameters, and DTOs/records use Jakarta Validation annotations (@NotBlank, @NotNull, @Positive, @Min, etc.) rather than manual if-checks in controllers",
"max_score": 10
},
{
"name": "Appropriate HTTP status codes",
"description": "Different error types return semantically correct HTTP status codes: 400 for validation, 404 for not-found, 409 for duplicate ISBN/email conflicts, 422 for business rule violations (e.g., max loans exceeded), 500 for unexpected errors",
"max_score": 10
},
{
"name": "DataIntegrityViolation handling",
"description": "DataIntegrityViolationException (or equivalent constraint violation) is caught and returns a user-friendly conflict response rather than leaking database constraint names",
"max_score": 7
},
{
"name": "CRUD endpoints functional",
"description": "The core endpoints are implemented and return appropriate success status codes (200 for reads, 201 for creation, proper responses for loan/return operations)",
"max_score": 10
}
]
}