Optivem Journal

Optivem Journal

Clean Architecture

Clean Architecture: Controllers Should NOT Catch SQL Exceptions

Error Handling - API layer

Valentina Jemuović's avatar
Valentina Jemuović
May 29, 2026
∙ Paid

🔒 Hello, this is Valentina with a premium issue of the Optivem Journal. I help Engineering Leaders & Senior Software Developers apply TDD in Legacy Code.


“How to handle errors properly?”

You’ve seen:

  • SQLException and DataAccessException caught inside controllers

  • catch (Exception e) returning a hand-rolled 500

  • giant try/catch blocks wrapping every endpoint

  • RuntimeException thrown and swallowed at random

And nobody agrees on the “right” way to do it.

Start where those mistakes happen — the API layer — and get one rule right: a controller turns errors into HTTP responses, and it should never reach for a database or framework exception to do it.

Error Handling at the API layer

This layer should turn errors into HTTP responses.

Examples:

  • HTTP status codes

  • error messages

  • API response bodies

❌ Controllers should NOT handle database/framework errors

@GetMapping("/orders")
public ResponseEntity<?> getOrders() {

    try {
        return ResponseEntity.ok(orderRepository.findAll());
    } catch (DataAccessException e) {
        return ResponseEntity.status(500).body("Database error");
    }
}

That’s the wrong place for database exception handling.


👉 I’m running a live workshop where we walk through a working e-shop example with a pipeline architecture, so you can see how it works in practice.

No rebuild tricks. No “it passed CI but broke anyway” surprises.

Join Pipelines Workshop →

€100 off with code EARLYBIRD100 — limited spots.


✅ The API layer should turn errors into responses — via a global exception handler

This post is for paid subscribers

Already a paid subscriber? Sign in
© 2026 Valentina Jemuović, Optivem · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture