Как лучше всего обрабатывать исключение ExecutionException?

У меня есть метод, который выполняет какую-то задачу с тайм-аутом. Я использую ExecutorServer.submit ()для получения объекта Future, а затем вызываю future.get ()с тайм-аутом. Это работает нормально, но мой вопрос - лучший способ обработки проверенных исключений, которые могут быть вызваны моей задачей. Следующий код работает и сохраняет проверенные исключения, но он кажется чрезвычайно неуклюжим и подвержен поломке, если список проверенных исключений в сигнатуре метода изменится.

Есть предложения, как это исправить? Мне нужно ориентироваться на Java 5, но мне также было бы любопытно узнать, есть ли хорошие решения в более новых версиях Java.

public static byte[] doSomethingWithTimeout( int timeout ) throws ProcessExecutionException, InterruptedException, IOException, TimeoutException {

    Callable<byte[]> callable = new Callable<byte[]>() {
        public byte[] call() throws IOException, InterruptedException, ProcessExecutionException {
            //Do some work that could throw one of these exceptions
            return null;
        }
    };

    try {
        ExecutorService service = Executors.newSingleThreadExecutor();
        try {
            Future<byte[]> future = service.submit( callable );
            return future.get( timeout, TimeUnit.MILLISECONDS );
        } finally {
            service.shutdown();
        }
    } catch( Throwable t ) { //Exception handling of nested exceptions is painfully clumsy in Java
        if( t instanceof ExecutionException ) {
            t = t.getCause();
        }
        if( t instanceof ProcessExecutionException ) {
            throw (ProcessExecutionException)t;
        } else if( t instanceof InterruptedException ) {
            throw (InterruptedException)t;
        } else if( t instanceof IOException ) {
            throw (IOException)t;
        } else if( t instanceof TimeoutException ) {
            throw (TimeoutException)t;
        } else if( t instanceof Error ) {
            throw (Error)t;
        } else if( t instanceof RuntimeException) {
            throw (RuntimeException)t;
        } else {
            throw new RuntimeException( t );
        }
    }
}

=== UPDATE ===

Многие люди публиковали ответы, в которых рекомендовалось либо 1 )re -бросать как общее исключение, либо 2 )re -бросать как непроверенное исключение. Я не хочу делать ничего из этого, потому что эти типы исключений (ProcessExecutionException, InterruptedException, IOException,TimeoutException )важны -, каждое из них будет обрабатываться по-разному при обработке вызова. Если бы мне не нужна была функция тайм-аута, то я бы хотел, чтобы мой метод выдавал эти 4 конкретных типа исключений (ну, за исключением TimeoutException ). Я не думаю, что добавление функции тайм-аута должно изменить сигнатуру моего метода, чтобы генерировать общий тип исключения.

38
задан assylias 27 June 2012 в 17:48
поделиться