Skip to content
Lektion undefined von undefined0/undefined abgeschlossen
Modul 6 — Error Handling

Error Handling — @ControllerAdvice & ProblemDetail

0 pts

Strukturiertes Error-Handling

Gute APIs geben strukturierte Fehler zurück — nicht Stacktraces.

Lektion 26: @ExceptionHandler

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ProductNotFoundException.class)
    public ResponseEntity<ProblemDetail> handleNotFound(ProductNotFoundException ex) {
        var problem = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage());
        problem.setProperty("productId", ex.getProductId());
        return ResponseEntity.status(404).body(problem);
    }
}

Lektion 27: @ControllerAdvice

@RestControllerAdvice = @ControllerAdvice + @ResponseBody. Es fängt Exceptions aus allen Controllern ab — ein zentraler Ort für Error-Handling.

Lektion 28: ProblemDetail (RFC 7807)

Spring Boot 3 liefert standardmäßig RFC 7807 Problem-Details:

{
  "type": "https://example.com/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Product 42 not found",
  "instance": "/api/products/42"
}

RFC 7807 — Standardisiertes Fehlerformat

RFC 7807 definiert application/problem+json als Media-Type für Fehler. Vorteile: maschinenlesbar, standardisiert, erweiterbar. Spring Boot 3 unterstützt es out of the box über ProblemDetail.

Lektion 29: Custom Exceptions

public class ProductNotFoundException extends RuntimeException {
    private final Long productId;
    public ProductNotFoundException(Long id) {
        super("Product " + id + " not found");
        this.productId = id;
    }
    public Long getProductId() { return productId; }
}

Lektion 30: Validation Errors & Global Format

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ProblemDetail> handleValidation(MethodArgumentNotValidException ex) {
    var problem = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "Validation failed");
    problem.setProperty("errors", ex.getBindingResult().getFieldErrors().stream()
        .map(fe -> Map.of("field", fe.getField(), "message", fe.getDefaultMessage()))
        .toList());
    return ResponseEntity.badRequest().body(problem);
}
Java Playground — Error Handling simuliertBereit
Editor wird geladen…

Exception-Hierarchie gezielt entwerfen

Zwei Basisklassen reichen: ResourceNotFoundException (404) und BusinessException (400/409). Jede Exception trägt Kontext-Daten (z. B. die fehlende ID). Der @RestControllerAdvice mappt Typen auf HTTP-Status — Services werfen nur Fachausnahmen, kein ResponseEntity.

Praxis-Szenario: CropGuard: GlobalExceptionHandler

Ein Farmer ruft PUT /api/claims/99/assess auf — der Claim existiert nicht. ClaimService wirft ResourceNotFoundException(99L). Der GlobalExceptionHandler baut ein ProblemDetail mit Status 404.

✅ Wichtige Erkenntnisse

Haken setzen, um deinen Lernfortschritt zu markieren:

    This site uses essential cookies for Stripe payments. No tracking cookies.