3

我正在寻找清理当前我正在处理的代码库的异常混乱。

基本设置是这样的。

我有一个由许多类实现的接口,如下所示:

public interface TerminalMessage<E> {

   // Override for specific return data type.
   public E send(TerminalStream stream) throws Exception;
}

这些类会抛出很多不同的异常,例如 IOException、InterruptedException 等。

就像现在一样,我所做的就是在捕获的异常上调用 getMessage() 并将此消息传递给 ui 代码。

这不是很好,因为我有时会收到向用户显示的虚假消息,并且我会捕获不需要的异常。

我正在考虑创建一个自定义异常类 (TerminalException) 来包装所有这些类型的异常。

但是我不确定在哪里进行包装,应该在第一次抛出异常的地方(例如在输出流中)还是在每个 send() 方法中进行包装。前者的优点是不会添加太多代码,但对我来说,流抛出 IOException 而不是 TerminalException 更有意义。

上面的设计也没有真正解决有时显示给用户的错误消息,所以一些关于如何将抛出的异常转换为对用户有用的东西的技巧会很棒!

谢谢!

4

3 回答 3

2

如果您在其中包含有用的信息(例如错误代码),则自定义异常是一个非常好的主意。

只需用您的 TerminalException 包装所有内容,但不要忘记原因

或者

使用抛出的第一个 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); 
     } 
 ´               

   }

} 
于 2012-04-24T07:48:15.120 回答
1

另一种选择可能是使用模板方法设计模式并“控制”其中的异常,如下所示:

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) {
        }
    }
}

这样,所有派生类的异常处理将是相同的并且是本地化的,并且派生类不必做任何特殊的事情。

于 2012-04-24T07:57:10.993 回答
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 正是与此有关。如果异常 si 不可管理系统必须关闭。因此,异常仅在一般错误处理程序的顶级应用程序中处理。这样可以防止异常爆炸。

于 2012-04-27T17:35:15.243 回答