我正在寻找清理目前我正在处理的代码库的异常混乱。
基本设置就是这样。
我有一个接口,由许多类实现,如下所示:
public interface TerminalMessage<E> {
// Override for specific return data type.
public E send(TerminalStream stream) throws Exception;
}
这些类抛出了许多不同的异常,如IOException,InterruptedException等。
就像现在一样,我所做的只是在捕获的异常上调用getMessage()并将此消息转发给ui-code。
这不是很好,因为我有时会向用户显示伪造的消息,并且我会捕获不必要的异常。
我正在考虑创建一个包含所有这些异常的自定义异常类(TerminalException)。
但是我不确定在哪里进行包装,是否应该在首次抛出异常(例如在输出流中)或每个send()方法中完成包装。前者的优点是不添加太多代码,但对我来说更有意义的是流抛出IOException而不是TerminalException。
上述设计也没有真正解决向用户显示的有时不好的消息,因此有关如何将抛出的异常转换为对用户有用的一些提示会很棒!
谢谢!
答案 0 :(得分:2)
如果您在其中包含有用信息(例如错误代码),则自定义异常是个好主意。
使用您的TerminalException包装所有内容,但不要忘记原因
OR
使用抛出的第一个TerminalException:
public class MyException extends Exception{
String errorMessage;
public MyException(String message, Exception cause){
super();
if(cause instanceof MyException){
// already wrapped
errorMessage= cause.getErrorMessage();
initCause(cause.getCause());
}
else{
// not my Exception
errorMessage=message;
initCause(cause);
}
´
}
}
答案 1 :(得分:1)
另一个选择可能是使用模板方法设计模式并“控制”其中的exeptions如下:
public abstract TerminalMessage<E> {
public abstract E doSend(TerminalStream stream);
public E send(TerminalStream stream) throws Exception {
// do common stuff here
try {
doSend(stream);
}
// catch more specific exceptions first
// handle all the exceptions accordingly here, thus controlling
// in one central location what will be thrown externally
catch(Exception) {
}
}
}
这样,所有派生类的异常处理将是相同的并且是本地化的,派生类不必执行任何特殊操作。
答案 2 :(得分:0)
从我尝试的许多设计中,这是我在一些项目中愉快地使用的最后一个。
public enum ExceptionCodes {
IOException("ioexception", false),
UserNotFound("usernotfond", true);
private static final String BUNDLE_NAME = "SOME_bundle_name";
private final String bundleCode;
private final String isManagable;
ExceptionCodes(String bundleCode, String isManagable) {
this. ...
...
}
public String message() {
// eventually get locale from somewhere, for example some threadLocal
return SomeBundleResolver.resolve(BUMDLE_NAME, bundleCode);
}
public Boolean isManagable() {
return isManagable;
}
}
public class MyGenericException extends RuntimeException {
private final ExceptionCodes exceptionCode;
private final Throwable throwable;
public MyException(ExceptionCodes exceptionCode) {
this....
...
}
public MyException(ExceptionCodes exceptionCode, Throwable throwable) {
this. ...
....
}
public Boolean isManagable() {
return exceptionCode.isManagable();
}
public String getMessage() {
return (throwable == null) ? super.getMessage() : throwable.getMessage();
}
...
}
重点是异常代码在一个地方进行管理。您可以将自定义属性添加到枚举中,例如错误代码等。异常的许多问题之一是,如果您不知道如何处理异常,那么您将无法理解如何处理上面的异常层。然后只会发生两种情况。这两种异常都可以以某种格式显示给用户,或者系统必须以一种优雅的方式崩溃。属性isManagable就是这个。如果异常不可管理的系统必须下降。因此,异常仅在一般错误处理程序中的顶层应用程序处理。这样就可以防止异常爆炸。