Closed regis-amaral closed 1 year ago
Pelo que entendi do problema, bastaria implementar o throws NoSuchElementException
no final de cada método das Interfaces de controllers que lidam com buscas de objetos individuais. Coisas como getById, getByName ou getByCodigo.
Assim a implementação da exceção fica obrigatória pelo contrato das interfaces com as Classes que as implementam.
Não entendi a necessidade da criação de classes novas para lidar com erros
É que essa solução não é obrigatória, não deixa claro para o dev que ele deve tratar a excessão. Ela pode ser ignorada e acabar estourando na execução do programa como está acontecendo ao buscar por um cliente com cpf inexistente.
Como eu não tenho muita experiência com error handling, joguei pro Gepeto dar o seu parecer também. Segue a conversa pra referência:
https://chat.openai.com/share/2b55d53f-c2df-4f92-abf2-437cd3c7a0e6
Basicamente, explicou em outras palavras a sua solução, e consegui entender melhor o contexto. Gostei também da sugestão de nomear a Classe de erro de uma maneira mais abstrata, para que possa ser usada por vários Controllers diferentes.
Segue um trecho da conversa:
Por exemplo, você poderia criar uma exceção EntityNotFoundException
, que poderia ser usada em qualquer método que busca uma entidade (como um Cliente, um Produto, etc.) e que pode não encontrar o que está procurando.
public class EntityNotFoundException extends Exception {
public EntityNotFoundException(String message) {
super(message);
}
}
Então, em seus métodos de busca, você poderia lançar essa exceção quando uma entidade não for encontrada:
public Cliente getClienteById(int id) throws EntityNotFoundException {
// Tenta encontrar o cliente
// Se o cliente não for encontrado, lança a exceção
if (!clienteRepository.existsById(id)) {
throw new EntityNotFoundException("Cliente com ID " + id + " não encontrado.");
}
// Se o cliente for encontrado, o retorna
return clienteRepository.findById(id);
}
Em qualquer lugar onde você chama getClienteById
, você seria então obrigado a tratar a EntityNotFoundException
.
try {
Cliente cliente = getClienteById(123);
// Faz algo com o cliente
} catch (EntityNotFoundException e) {
// Faz algo em resposta à exceção (por exemplo, loga o erro e/ou retorna uma mensagem de erro ao usuário)
}
Contém implementação de um dos erros. Podemos deixar essa Issue aberta para pensarmos em outras classes de erros
Classe já adotada na main
, agora é preciso apenas garantir a sua adoção quando for apropriado
Enquanto estava testando algumas views, várias requisições de recursos, quando poderiam ser nulas, agora só estão lançando a Exception e interrompendo a execução do aplicativo:
Por exemplo, no CadastrarReservaView
public class CadastrarReservaView {
static void cadastrarReserva(IReservaController reservaController, IClienteController clienteController, IMesaController mesaController) {
Reserva reserva = new Reserva();
Cliente cliente;
try {
String cpfCliente = solicitaEntradaDeDado("Informe o CPF do cliente:");
cliente = clienteController.recuperarPorCpf(cpfCliente);
if (cliente == null) {
exibeDialogo("Cliente não encontrado! Vamos cadastrá-lo agora.");
cadastrarCliente(clienteController);
cliente = clienteController.recuperarPorCpf(cpfCliente);
if (cliente == null) {
exibeDialogo("Ocorreu um erro ao tentar cadastrar o cliente. Tente novamente.");
return;
}
}
Quando tentei por uma rota de criação caso cliente fosse nulo, a Exception impossibilita esse tipo de feature
Caused by: org.ravin.utils.exceptions.EntidadeNaoEncontradaException: Cliente não encontrado para o CPF: 3423
Como em breve esse sistema irá se tornar uma API, e as Exceptions serão respostas HTTP, não precisamos redesenhar nossa lógica de Exceptions, mas por enquanto vamos ter isso em mente caso sejam criadas interfaces que possam lidar com valores nulos
Métodos de classes que disparam intencionalmente a exceção NoSuchElementException devem declarar uma throws para que quem as chamar seja informado (o ideal era ser obrigado) a tratar a exceção:
Controller como deveria ser:
Interface como deveria ser:
Chamada do método atualmente:
Como a chamada deve ser tratada:
Precisamos ajustar isso na classe ClienteController e combinar de utilizarmos nas demais implementações de código que lançarem excessões sempre que um objeto não for encontrado;
Infelizmente a NoSuchElementException é uma exceção não verificada, o que não obrigada quem chamar o método a implementar o tratamento da exceção. Logo, o dev terá sempre que se lembrar, e isso não é o melhor cenário quando se sabe que uma exceção será lançada sempre que um objeto não for encontrado na pesquisa.
Exceções verificadas, as que obrigam o dev a implementar o tratamento ou repassar para frente usando throws, não podem ser lançadas como as não verificadas:
throw new NoSuchElementException("...");
Minha sugestão seria criar uma exceção verificada para nosso caso em particular, exemplo: