Interview Prep Zoneby CuriouserLabs

Question 1 of 5 · senior level

Checked vs unchecked exceptions — what's your position as an API designer, and why has the industry largely moved to unchecked?

🎤 Say this first

Checked exceptions force callers to acknowledge recoverable conditions at compile time — a beautiful idea that aged badly: they don't compose with lambdas/streams, they leak implementation details through layers, and in practice they breed catch (Exception e) { /* ignored */ }. Modern consensus (Spring, Hibernate, most new APIs): unchecked by default, with a well-designed exception hierarchy; reserve checked for the rare close-to-the-call recoverable case where the caller realistically has a different action to take.

The full picture

  • The test: can the immediate caller realistically recover with a different action? If yes (e.g., InterruptedException, a retryable payment decline modeled explicitly), checked can earn its keep. If the only realistic response is fail-the-request, unchecked.
  • Layering rule: never let SQLException cross a service boundary — translate at the boundary into your domain's hierarchy (OrderNotFound, PaymentDeclined, InfrastructureException). Spring's DataAccessException translation is this principle industrialized.
  • Wrap, don't swallow: throw new DomainException("context", cause) — always chain the cause; a lost stack trace turns a 10-minute fix into a day.
  • Lambdas broke checked: Stream.map(o -> repo.load(o)) won't compile if load throws checked — hence sneaky-throw hacks and wrapper ceremony. New APIs avoid inflicting that.
Boundary translation
public Order load(OrderId id) {
    try {
        return jdbc.queryForObject(SQL, mapper, id.value());
    } catch (EmptyResultDataAccessException e) {
        throw new OrderNotFoundException(id, e);      // domain-speak + cause
    }
    // infrastructure exceptions bubble as-is; a @ControllerAdvice
    // maps: OrderNotFound -> 404, DomainValidation -> 422, rest -> 500
}

🔄 Likely follow-up questions

  • How would you model 'payment declined' — exception or result type — and why?
  • What is exception translation and where should it live?
  • Why does InterruptedException deserve special handling? (restore the interrupt flag)