Olá.
Gostaria de tirar uma dúvida. Há pouco tempo atrás, tivemos um debate no trabalho sobre como seria a melhor forma de passar o tipo de erro ocorrido na camada de serviço para a camada de visão.
Por padrão nosso, a camada de serviço gera somente uma classe nossa que estende Exception, chamada ServiceException. Também por padrão, ServiceException é a única exceção lançada pelas classes dessa camada.
(...)
public class ServiceException extends Exception
(...)
Eu tive um requisito no qual eu faria uma série de operações na camada de serviço e, caso fosse necessário, devo emitir uma mensagem de erro específica para o usuário, dependendo do problema encontrado. Vamos supor que precise avisar ao usuário, além dos erros comuns, especificamente de violação da regra de negócio X e da violação da regra de negócio Y. Então, o problema é avisar à camada de visão qual tipo de problema ocorreu, para que ela saiba qual mensagem exibir.
Eu havia implementado da seguinte forma:
public class ServiceException extends Exception
(...)
public class RegraXException extends ServiceException
(...)
public class RegraYException extends ServiceException
(...)
Na camada de serviço, fazia:
(...)
try {
(...)
if (violacaoRegraX) {
throw new RegraXException();
}
if (violacaoRegraY) {
throw new RegraYException();
}
} catch (Exception e) {
throw new ServiceException(e);
}
Na visão, tinha:
(...)
try {
(...)
} catch (RegraXException xe) {
//manda msg de violação da Regra X
} catch (RegraYException xe) {
//manda msg de violação da Regra Y
} catch (ServiceException e) {
//manda msg de erro inesperado
}
Porém, meus colegas, quando viram meu código, argumentaram que essa era uma péssima prática e que seria melhor usar somente um enum como atributo de ServiceException, que definiria qual foi o erro encontrado. A idéia seria evitar uma subclasse de exceção para cada violação de regra de negócio possível.
(...)
public class ServiceException extends Exception {
(...)
public ServiceException(ServiceExceptionEnum tipoExcecao) {
this.tipoExcecao = tipoExcecao;
}
private ServiceExceptionEnum tipoExcecao;
//getter e setter
}
public enum ServiceExceptionEnum {
VIOLACAO_REGRA_X,
VIOLACAO_REGRA_Y
}
e nas camadas de serviço e visão ficaria:
//SERVIÇO
(...)
try {
(...)
if (violacaoRegraX) {
throw new ServiceException(ServiceExceptionEnum.VIOLACAO_REGRA_X);
}
if (violacaoRegraY) {
throw new ServiceException(ServiceExceptionEnum.VIOLACAO_REGRA_Y);
}
} catch (Exception e) {
throw new ServiceException(e);
}
//VISÃO
(...)
try {
(...)
} catch (ServiceException e) {
if (e.tipoExcecao == ServiceExceptionEnum.VIOLACAO_REGRA_X) {
//manda msg de violação da Regra X
} else if (e.tipoExcecao == ServiceExceptionEnum.VIOLACAO_REGRA_Y) {
//manda msg de violação da Regra Y
} else {
//manda msg de erro inesperado
}
}
Sinceramente, para mim é quase a mesma coisa. Eu só acho ruim a solução dos enums porque obriga que toda exceção de regra de negócios seja cadastrada numa classe só e não sei se isso é bom.
Qual a opinião de vcs?