2008-11-19 4 views
1

Serait-il utile d'ajouter un moyen générique d'ajouter des informations à un Throwable sans créer un nouveau Throwable?Générique d'ajouter des informations à un Throwable sans créer un nouveau Throwable

Je vois souvent du code comme ceci:

try { 
    foo(); 
} catch(Exception e) { 
    throw new Exception(e.getMessage() + " extra info=" + blah, e); 
} 

Serait-il préférable d'ajouter à la place Throwable.setProperty (String key, String value) de sorte que le code ci-dessus est reformulé comme suit?

try { 
    foo(); 
} catch(Exception e) { 
    e.setProperty("extra info", blah); 
    throw e; 
} 

Les informations supplémentaires peuvent s'imprimer (une par ligne) entre le message et la liste de piles. Avantages: 1. Ne nécessiterait pas la création de nouveaux Throwables juste pour ajouter des informations supplémentaires. 2. Les traces de pile n'ont pas plusieurs couches de traces de cause (et donc sont plus faciles à lire) 3. Réduire le coût de création de traces de pile supplémentaires.

+0

Si vous vous inquiétez du coût de Throwable.fillInStackTrace(), alors j'ose dire que vous le faites mal :) (en supposant que votre définition de «coût» soit liée aux cycles du processeur.) –

+0

Je ne suis pas inquiet à propos de nouveaux Throwables prenant une quantité significative du CPU - mais même en supprimant une petite quantité de CPU gaspillée est bénéfique. –

Répondre

0

En général, je pense qu'il est préférable d'utiliser les idiomes standard dans des cas comme celui-ci. Dans ce cas, l'idiome standard consiste à envelopper l'exception, comme ceci:

try { 
    foo(); 
} catch (Exception e) { 
    throw new MySpecificException("extra info=" + blah, e); 
} 

De plus, en général, il est préférable de ne pas attraper des exceptions génériques. Si vous souhaitez capturer et ajouter des informations à RuntimeException, faites-le et créez une nouvelle exception RuntimeException. Sinon, réfléchissez bien aux exceptions vérifiées que vous souhaitez capturer et lancer.

3

Les exceptions chaînées prennent déjà en compte la suppression des trames de pile redondantes. C'est-à-dire que vous ne verrez qu'un cadre de pile donné une seule fois. C'est une question d'opinion, mais je considère l'absence d'exception enchaînée comme un inconvénient.

Déconseiller l'extension de RuntimeException serait bon. Cela pourrait aider à cet égard.

Les cadres de pile interactifs peuvent souhaiter ajouter leur propre contexte lorsque la pile se déroule. Cela pourrait conduire à la confusion des propriétés. Il devrait y avoir un mécanisme pour traiter cela, comme une pile de valeurs pour un nom de propriété donné.

Cela n'arrivera jamais dans Java, mais rien ne vous empêche d'utiliser cette convention pour vos propres classes Exception.

+0

Cela ne supprime pas les exceptions chaînées - ajoutez simplement une alternative lorsque vous ne souhaitez pas modifier la classe Throwable. Clutant: Peut-être qu'une liste de lignes de chaîne est meilleure. –

1

Comme d'habitude, avec les exceptions, cela dépend beaucoup du scénario. Bien que vous devriez essayer et être spécifique à quelles exceptions vous attrapez, vous voulez également être explicite quant à la raison des exceptions dans la portée actuelle et ne pas augmenter les exceptions levées d'une autre portée. Si vous n'avez rien à ajouter qui puisse aider l'appelant et ne peut pas effectuer d'action en réponse à l'exception spécifique, laissez-le se propager. S'il y a des informations de votre portée qui seront pertinentes pour l'appelant, lancez votre exception avec vos informations, enchaînées à l'exception interceptée. La clé ici est la portée. Toujours produire des résultats à partir de la portée actuelle et permettre aux autres portées de faire de même.

Questions connexes