Skip to main content

4.5 Custom Exceptions & Enterprise Best Practices

← Back to Chapter 4: Exception Handling

In production enterprise architectures, standard library exceptions like IllegalArgumentException are often too generic to communicate specific business-domain failures.


Why use custom exceptions?​

Instead of:

RuntimeException

you can clearly communicate:

UserNotFoundException
PaymentFailedException
OrderNotFoundException

This makes code:

  1. easier to understand
  2. easier to maintain
  3. easier to debug
  4. easier to handle differently

Custom checked vs unchecked exception​

You can create both.

Checked custom exception

Exception
class MyException extends Exception {
}

Caller must handle or declare it.

Unchecked custom exception

RuntimeException
class MyException extends RuntimeException {
}

Caller isn't forced by compiler to handle it.

Which one is usually preferred in Spring Boot?​

For business/application exceptions, unchecked exceptions extending RuntimeException are commonly preferred.

Why we should not use Exception everywhere?​

You might see:

try {
// code
} catch (Exception e) {
// do something
}

This is usually not a good practice.

Why?

Because it catches almost everything under Exception and can hide the actual problem.

Better:

catch (UserNotFoundException e)

or:

catch (SQLException e)

Why @RestControllerAdvice?​

It allows us to define exception handling in one central location instead of writing:

try-catch

inside every controller method.

Without global handling:

Controller 1 → try/catch
Controller 2 → try/catch
Controller 3 → try/catch
Controller 4 → try/catch

Messy.

With global handling:

Global Exception Handler
/ | \
/ | \
Controller 1 Controller 2 Controller 3

Much cleaner.

@ExceptionHandler​

Inside a global exception handler, we commonly use:

@ExceptionHandler

It tells Spring:

"When this particular exception occurs, use this method to generate the response."

For example:

UserNotFoundException
↓
@ExceptionHandler(UserNotFoundException.class)
↓
HTTP 404 response