¿Por qué Chain exception?
Tenemos que encadenar las excepciones para que los registros sean legibles.
Take siguientes ejemplos de 1. Sin encadenamiento y 2. encadenamiento, excepciones a sentir la diferencia
Crear siguientes excepciones
class NoLeaveGrantedException extends Exception {
public NoLeaveGrantedException(String message, Throwable cause) {
super(message, cause);
}
public NoLeaveGrantedException(String message) {
super(message);
}
}
class TeamLeadUpsetException extends Exception {
public TeamLeadUpsetException(String message, Throwable cause) {
super(message, cause);
}
public TeamLeadUpsetException(String message) {
super(message);
}
}
class ManagerUpsetException extends Exception {
public ManagerUpsetException(String message, Throwable cause) {
super(message, cause);
}
public ManagerUpsetException(String message) {
super(message);
}
}
class GirlFriendOfManagerUpsetException extends Exception {
public GirlFriendOfManagerUpsetException(String message, Throwable cause) {
super(message, cause);
}
public GirlFriendOfManagerUpsetException(String message) {
super(message);
}
}
Ahora ellos
1 utilizar. Sin encadenar
public class MainClass {
public static void main(String[] args) throws Exception {
getLeave();
}
static void getLeave() throws NoLeaveGrantedException {
try {
howIsTeamLead();
} catch (TeamLeadUpsetException e) {
e.printStackTrace();
throw new NoLeaveGrantedException("Leave not sanctioned.");
}
}
static void howIsTeamLead() throws TeamLeadUpsetException {
try {
howIsManager();
} catch (ManagerUpsetException e) {
e.printStackTrace();
throw new TeamLeadUpsetException(
"Team lead is not in good mood");
}
}
static void howIsManager() throws ManagerUpsetException {
try {
howIsGirlFriendOfManager();
} catch (GirlFriendOfManagerUpsetException e) {
e.printStackTrace();
throw new ManagerUpsetException("Manager is in bad mood");
}
}
static void howIsGirlFriendOfManager()
throws GirlFriendOfManagerUpsetException {
throw new GirlFriendOfManagerUpsetException(
"Girl friend of manager is in bad mood");
}
}
2.Encadenando
public class MainClass {
public static void main(String[] args) throws Exception {
getLeave();
}
static void getLeave() throws NoLeaveGrantedException {
try {
howIsTeamLead();
} catch (TeamLeadUpsetException e) {
throw new NoLeaveGrantedException("Leave not sanctioned.", e);
}
}
static void howIsTeamLead() throws TeamLeadUpsetException {
try {
howIsManager();
} catch (ManagerUpsetException e) {
throw new TeamLeadUpsetException(
"Team lead is not in good mood", e);
}
}
static void howIsManager() throws ManagerUpsetException {
try {
howIsGirlFriendOfManager();
} catch (GirlFriendOfManagerUpsetException e) {
throw new ManagerUpsetException("Manager is in bad mood", e);
}
}
static void howIsGirlFriendOfManager()
throws GirlFriendOfManagerUpsetException {
throw new GirlFriendOfManagerUpsetException(
"Girl friend of manager is in bad mood");
}
}
Ahora compara los registros de
1. Sin encadenamiento
com.bskyb.svod.autoingest.GirlFriendOfManagerUpsetException: Girl friend of manager is in bad mood
at com.bskyb.svod.autoingest.MainClass.howIsGirlFriendOfManager(MainClass.java:61)
at com.bskyb.svod.autoingest.MainClass.howIsManager(MainClass.java:52)
at com.bskyb.svod.autoingest.MainClass.howIsTeamLead(MainClass.java:43)
at com.bskyb.svod.autoingest.MainClass.getLeave(MainClass.java:34)
at com.bskyb.svod.autoingest.MainClass.main(MainClass.java:29)
com.bskyb.svod.autoingest.ManagerUpsetException: Manager is in bad mood
at com.bskyb.svod.autoingest.MainClass.howIsManager(MainClass.java:55)
at com.bskyb.svod.autoingest.MainClass.howIsTeamLead(MainClass.java:43)
at com.bskyb.svod.autoingest.MainClass.getLeave(MainClass.java:34)
at com.bskyb.svod.autoingest.MainClass.main(MainClass.java:29)
com.bskyb.svod.autoingest.TeamLeadUpsetException: Team lead is not in good mood
at com.bskyb.svod.autoingest.MainClass.howIsTeamLead(MainClass.java:46)
at com.bskyb.svod.autoingest.MainClass.getLeave(MainClass.java:34)
at com.bskyb.svod.autoingest.MainClass.main(MainClass.java:29)
Exception in thread "main" com.bskyb.svod.autoingest.NoLeaveGrantedException: Leave not sanctioned.
at com.bskyb.svod.autoingest.MainClass.getLeave(MainClass.java:37)
at com.bskyb.svod.autoingest.MainClass.main(MainClass.java:29)
2. encadenar
Exception in thread "main" com.bskyb.svod.autoingest.NoLeaveGrantedException: Leave not sanctioned.
at com.bskyb.svod.autoingest.MainClass.getLeave(MainClass.java:36)
at com.bskyb.svod.autoingest.MainClass.main(MainClass.java:29)
Caused by: com.bskyb.svod.autoingest.TeamLeadUpsetException: Team lead is not in good mood
at com.bskyb.svod.autoingest.MainClass.howIsTeamLead(MainClass.java:44)
at com.bskyb.svod.autoingest.MainClass.getLeave(MainClass.java:34)
... 1 more
Caused by: com.bskyb.svod.autoingest.ManagerUpsetException: Manager is in bad mood
at com.bskyb.svod.autoingest.MainClass.howIsManager(MainClass.java:52)
at com.bskyb.svod.autoingest.MainClass.howIsTeamLead(MainClass.java:42)
... 2 more
Caused by: com.bskyb.svod.autoingest.GirlFriendOfManagerUpsetException: Girl friend of manager is in bad mood
at com.bskyb.svod.autoingest.MainClass.howIsGirlFriendOfManager(MainClass.java:58)
at com.bskyb.svod.autoingest.MainClass.howIsManager(MainClass.java:50)
... 3 more
ok Mi punto era: ¿qué pasaría con los siguientes cambios (que muestran solo los cambios necesarios aquí)? 'try {} catch (SQLException e) {} catch (ResourceLoadException f) {}'. Pero entiendo tu punto sobre tener una Excepción más cercanamente relacionada. Pero ahora mi pregunta sería, si la excepción personalizada no tiene nada que ver con la excepción real causada, es decir, si la excepción en realidad es 'SQLException' y no' ResourceLoadException', que el código de manejo de excepciones podría ser un error? –
Nada estaría * mal * con ese cambio de código, pero como dije, puede no tener ningún sentido, tener que atrapar 'SQLException' en ese nivel de abstracción. ¿Qué ocurre si, por ejemplo, hay dos clases de carga de recursos: 'MysqlResourceLoader' y' FileResourceLoader' y comparten una interfaz común, 'ResourceLoader'. Entonces el método 'loadResource' obviamente no debería declararse para lanzar' SQLException'. (¿Qué sucede si le doy un 'ResourceLoader' y no sabe si es del tipo real?) – aioobe
El punto es que puede tener una interfaz que arroje un tipo de excepción específico en el nivel de abstracción. En la implementación de esa interfaz puede ser necesario capturar una SQLException o de lo contrario. El objetivo de una interfaz es quedarse con ella y no tener que cambiarla, sin importar cuál sea la esencia de la implementación ... si eso tiene sentido. Además, en este caso, la clase principal no tendrá idea de qué hacer con una SQLException. Lo único que tiene que hacer es concluir "estamos jodidos", imprimir un error y hacer que el usuario lo solucione. – user606723