Careeroza
Custom Exceptions
Exceptions That Describe Business Problems
package com.shopease.common.error;
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String resource, Object id) {
super(resource + " " + id + " not found");
}
}
public class InsufficientStockException extends RuntimeException {
public InsufficientStockException(String product, int requested, int available) {
super("Only " + available + " left of " + product + ", requested " + requested);
}
}
public class DuplicateSkuException extends RuntimeException {
public DuplicateSkuException(String sku) {
super("SKU " + sku + " already exists");
}
}- Extend
RuntimeException(unchecked): service methods stay clean and@Transactionalrolls back on them by default. - Name them after the business problem, not the HTTP status. The service should not know about HTTP.
Throwing Them from the Service
@Service
public class ProductService {
private final ProductRepository repository;
public ProductService(ProductRepository repository) { this.repository = repository; }
public Product getById(Long id) {
return repository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Product", id));
}
public Product reserve(Long id, int quantity) {
Product p = getById(id);
if (p.getStock() < quantity)
throw new InsufficientStockException(p.getName(), quantity, p.getStock());
p.setStock(p.getStock() - quantity);
return repository.save(p);
}
}Note: ResponseStatusException (e.g. throw new ResponseStatusException(HttpStatus.NOT_FOUND, "...")) is fine for quick prototypes, but it ties your service to HTTP. Prefer your own exceptions plus a handler.