2012-04-24 5 views
2

Я ищу, чтобы очистить беспорядок исключения, который в настоящее время является базой кода, над которой я работаю.Как очистить обработку исключений?

Основная настройка - это.

У меня есть интерфейс, реализуемый множеством классов, выглядит следующим образом:

public interface TerminalMessage<E> { 

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

Эти классы бросают много различных исключений, как IOException, InterruptedException и т.д.

Как это теперь все, что я делаю, это вызов getMessage() в зацепившихся исключениях и передача этого сообщения в u-код.

Это не очень приятно, так как иногда я получаю ложные сообщения, отображаемые пользователю, и я улавливаю нежелательные исключения.

Я собираюсь создать собственный класс исключений (TerminalException), который будет обертывать все эти исключения.

Однако я не уверен, где сделать обертывание, если обертывание должно выполняться там, где исключение сначала выбрано (например, в выходном потоке) или в каждом методе send(). Преимущество первого заключается в том, что он не добавляет много кода, но имеет смысл, что поток генерирует исключение IOException, а не исключение TerminalException.

Вышеупомянутая конструкция также не позволяет решить иногда плохие сообщения, отображаемые пользователю, поэтому некоторые советы о том, как превратить заброшенные исключения во что-то полезное для пользователя, были бы замечательными!

Спасибо!

+2

Я настоятельно рекомендую вам прочитать эту статью http://onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=2 – aviad

ответ

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); 
    } 
´    

    } 

} 
+0

Таким образом, бросая исключение TerminalEx, которое обертывает исключение IO вниз на самом низком уровне уровень (в моем классе пользовательских потоков) должен быть в порядке? – monoceres

+1

@monoceres Я бы сказал, что вы всегда должны поймать исключение, где оно «имеет смысл». Если ваш класс потока может добавить дополнительную информацию (например, имя файла, номер строки в файле или какое-то важное состояние), чем предоставляет голый IOException, поймать его и вывести в качестве причины новое исключение, включая информацию и исключение IOException. Если он не может добавить новую информацию, пусть она пузырится до слоя, который способен. Конечно, вы можете повторять это столько раз, сколько хотите, или это имеет смысл. – siegi

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

Таким образом, обработка исключений для всех производных классов будет одинаковой и локализованной, а производные классы не должны делать ничего особенного.

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 - это именно об этом. Если исключающая система не управляется, она должна опуститься. Таким образом, исключение обрабатывается только на верхнем уровне приложения в общем обработчике ошибок.Таким образом, вы можете предотвратить взрыв Exception.

Смежные вопросы