Вы здесь:

По мотивам статьи Изучаем ResponseEntity<?> и избавляемся от него в контроллерах Spring Boot
В заметке рассмотрено 2 способа:

1. Способ с возвратом ResponseEntity<?>
2. Способ с возвратом объекта

1. Способ с возвратом ResponseEntity<?>

Возвращается ResponseEntity<?>.

@GetMapping("/{message}")
public ResponseEntity<?> echo(@PathVariable("message") String message) {
    if (message == null || message.isEmpty() || message.equals("test_error")) {
      return ResponseEntity.status(HttpStatus.BAD_GATEWAY).body("message is empty"); // error cod 502
    }

    if (message.length() < 2) {
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("message is too short"); // error cod 503
    } else {
        return ResponseEntity.ok(new SimpleObj(message));
    }
}

ResponseEntity<?> - это обертка над HttpStatus и Object. Возвращается в любом случае, даже если объект не найден. Т.е. можно не обрабатывать исключения. Для более полного описания ошибки можно сделать так (с помощью AppError):

@GetMapping("/products")
public ResponseEntity<?> getProduct(Long id){
    try {
        Product product = productsService.findById(id).orElseThrow();
            return new ResponseEntity<>(product, HttpStatus.OK); // Возврат объекта
    } catch (Exception e) {
        return new ResponseEntity<>(
            new AppError(
                    HttpStatus.NOT_FOUND.value(),
                    "Product with id " + id + " not found"),HttpStatus.NOT_FOUND
            );
        }
}

где AppError это простой класс:

public class AppError {
    private int statusCode;
    private String message;

    public AppError() {}

    public AppError(int statusCode, String message) {
        this.statusCode = statusCode;
        this.message = message;
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

Тестировать с помощью ResponseEntity. Некрасиво, что возвращается в виде ResponseEntity<?>.
Пример https://github.com/cherepakhin/response_entity

2. Способ с возвратом объекта

@RestController
@RequestMapping("/simpleobj")
public class SimpleObjRest {
    @GetMapping("/{message}")
    public SimpleObj getMessageWithExcption(@PathVariable("message") String name) throws MyResourceException {
        if (name.equals("error")) {
            throw new MyResourceException("Exception for name=error");
        }
        return new SimpleObj(name);
    }
}

где MyResourceException.java это класс исключения:

public class MyResourceException extends Throwable {
    public MyResourceException(String message) {
        super(message);
    }
}

и обработка MyResourceException через Advice и Handler в классе GlobalExceptionHandler.java:

@ControllerAdvice // <---------------- Advice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { // <---------  Handler
    private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler
    public ResponseEntity catchResourceNotFoundException(MyResourceException e) { // <---- MyResourceException !!!
        logger.error("GlobalExceptionHandler.catchResourceNotFoundException");
        logger.error(e.getMessage(), e);
        return new ResponseEntity(new AppError(e.getMessage()), HttpStatus.SERVICE_UNAVAILABLE); // <- AppError !!!
    }
}

где AppError.java:

public class AppError {
    private String message;

    public AppError() {
        this("Internal Server Error");
    }

    public AppError(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof AppError)) return false;
        AppError appError = (AppError) o;
        return Objects.equals(message, appError.message);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(message);
    }
}

(про ResponseBody см. https://www.baeldung.com/spring-request-response-body).
Просто тестировать.
Пример https://github.com/cherepakhin/object_and_excp

Ссылки:

Tutorial: Thymeleaf + Spring