Catch The Exception

For each scenario, choose where to throwand where to catch the exception. The goal is to push errors to the right layer and handle them at the right boundary.

1. Validating user input in a service layer
You have a REST controller that calls a service. The service validates input and interacts with a repository. Where should you throw and catch the exception if the input is invalid?
// Controller
public UserResponse createUser(@RequestBody CreateUserRequest request) {
    // 1) call into service
    User user = userService.createUser(request);
    return UserResponse.from(user);
}

// Service
public User createUser(CreateUserRequest request) {
    // TODO: validate request
    // TODO: talk to repository
}

// Repository
public User save(User user) {
    // writes to DB
}

Where should you throw and where should you catch?

Pick an option to see the explanation.

2. Database failure while saving an order
Your service calls a repository to save an order. The DB occasionally fails (network blip). Where do you throw, and where do you catch?
// Service
public void placeOrder(OrderRequest request) {
    Order order = buildOrder(request);
    orderRepository.save(order); // may fail
    // send confirmation email
}

// Repository
public void save(Order order) {
    // insert into DB
}

Where should you throw and where should you catch?

Pick an option to see the explanation.

3. Unexpected bug in a handler
You have a top-level request handler (HTTP or Kafka consumer). A random NullPointerException occurs deep in the call stack. Where is the best place to catch it?
public void handleMessage(Event event) {
    // 1) parse event
    // 2) call service
    // 3) log result
    // Somewhere deep inside, a NullPointerException might be thrown
}

Where should you throw and where should you catch?

Pick an option to see the explanation.