2012-10-10 23 views
13

¿cuál es la mejor práctica para manejar InterruptedException s cuando se usa Throwables.propagate (e) en Guava?Guava: Throwables.propagate e InterruptedException

Me encanta usar throw Throwables.propagate(e), especialmente en métodos que no arrojan excepciones marcadas y donde el manejo de excepciones es responsabilidad de la persona que llama. Pero no hace lo que esperaría con InterruptedException.

no quiero perder el hecho de que el hilo se interrumpe, por lo que termino de escribir cosas como:

public void run() { 
    Callable c = ...; 
    try { 
     c.call(); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
     throw Throwables.propagate(e); 
    } catch (Exception e) { 
     throw Throwables.propagate(e); 
    } 
} 

¿Hay una manera de hacer esto en guayaba? ¿Existe una forma (compatible con versiones anteriores ?!) de usar algo como Throwables.propagate() que establece el hilo como interrumpido, si está envolviendo y propagando una InterruptedException?

+1

Lo plantearía como una solicitud de función dentro de Guava – artbristol

Respuesta

7

Convenientemente, lo discutimos internamente hace un tiempo. Voy a copiar y pegar:

Mi opinión de la línea dura en Throwables.propagate(e) es que es básicamente throw new RuntimeException(e) y que la gente por lo general no deben hacerlo, al igual que por lo general no deben escribir throw new RuntimeException(e). (Y si van a escribirlo, también podrían escribirlo directamente para que quede claro lo que está sucediendo.)

Mi opinión de línea dura en catch (Exception e) - por lo general, cómo las personas se meten en este lío - es que generalmente tampoco deberían hacer eso. (Obviamente hay casos en los que catch (Exception e) es obviamente lo correcto (básicamente cualquier nivel superior, bloque catch de alcance de operación), pero esos son ... obvios).

Mi opinión de línea dura en InterruptedException es que tener InterruptedException implementar Exception en absoluto está roto de esta manera: requiere un manejo especial que otras excepciones no lo hacen.

Mi opinión de línea dura en la conversión de InterruptedException a un RuntimeException es "do not." (Esto, como muchas de las otras cosas que he dicho anteriormente, es polémico.)

Por un lado, no estoy seguro de que haya algo que podamos hacer para salvar propagate(). Por otro lado, tal vez es bueno hacer que el método sea un poco menos malo.

Por otra parte, considerar esta persona que llama, que coge ExecutionException e:

throw Throwables.propagate(e.getCause());

Sería un error para interrumpir el hilo consumidor, al igual que sería un error para lanzar e.getCause() directamente, debido a la interrupción fue pensado para el hilo informático, no el hilo del consumidor.

Estoy inclinado a dejar propagate() solo. (Como probablemente pueda adivinar, personalmente estoy inclinado a desaprobarlo, pero esa es una discusión más amplia.)

+1

+1 puntos interesantes. Me sorprende que la gente escriba 'throw Throwables.propagate (e.getCause());'! ¡La traza de la pila parecería que todo sucedió en un solo hilo! – artbristol

+1

Gracias, puntos interesantes. +1 a InterruptedException implementando excepciones que son incorrectas, pero Java está donde está. Creo que la conversión de InterruptedException a RuntimeException a veces es esencial: si la firma de mi método está solucionada por una interfaz externa (por lo que no puedo lanzar InterruptedException), y mi operación fue interrumpida (por lo que no puedo cumplir mi contrato), debe lanzar una excepción. ¿Qué otra opción sensata existe aparte de configurar el hilo como interrumpido y lanzar una RuntimeException? –

+4

Para escribir 'throw new RuntimeException (e)', es molesto tener una excepción que envuelve la excepción (especialmente cuando no agrega nada útil, como un mensaje adicional sobre el contexto actual). Dondequiera que se pueda evitar ese ruido (por ejemplo, ya es una excepción sin marcar), genial. Existe la creencia de que las API deben usar excepciones sin marcar siempre que sea posible. Incluso si uno no compra ese argumento, uno todavía tiene que implementar las interfaces de otras personas escritas de esa manera. Así que por favor no desaprobar 'Throwables.propagate (e)'! –

Cuestiones relacionadas