différence entre jeter et lancer de nouvelles exceptions ()

quelle est la différence entre

try { ... } catch{ throw } 

et

 try{ ... } catch(Exception e) {throw new Exception(e.message) } 

Indépendamment du fait que le second montre un message?

throw; renvoie l’exception d’origine et conserve sa trace de stack d’origine.

throw ex; lève l’exception d’origine, mais réinitialise la trace de la stack, détruisant toutes les informations de trace de la stack jusqu’à votre bloc catch .

N’écrivez JAMAIS throw ex;

throw new Exception(ex.Message); est encore pire. Il crée une nouvelle instance d’ Exception , perdant la trace de stack d’origine de l’exception, ainsi que son type. (par exemple, IOException ).
En outre, certaines exceptions contiennent des informations supplémentaires (par exemple, ArgumentException.ParamName ).
throw new Exception(ex.Message); va détruire cette information aussi.

Dans certains cas, vous souhaiterez peut-être envelopper toutes les exceptions dans un object d’exception personnalisé, afin de pouvoir fournir des informations supplémentaires sur ce que faisait le code lorsque l’exception a été générée.

Pour ce faire, définissez une nouvelle classe qui hérite d’ Exception , ajoutez les quatre constructeurs d’exception , et éventuellement un constructeur supplémentaire qui prend une InnerException et des informations supplémentaires, et lancez votre nouvelle classe d’exception, en passant ex comme paramètre InnerException . En transmettant l’ InnerException origine, vous conservez toutes les propriétés de l’exception d’origine, y compris la trace de la stack.

Le premier préserve le stacktrace original:

 try { ... } catch { // Do something. throw; } 

La seconde vous permet de modifier le type de l’exception et / ou le message et d’autres données:

 try { ... } catch (Exception e) { throw new BarException("Something broke!"); } 

Il y a aussi une troisième voie où vous passez une exception interne:

 try { ... } catch (FooException e) { throw new BarException("foo", e); } 

Je recommande d’utiliser:

  • le premier si vous souhaitez effectuer un nettoyage en cas d’erreur sans détruire les informations ni append d’informations sur l’erreur.
  • le troisième si vous voulez append plus d’informations sur l’erreur.
  • la seconde si vous souhaitez masquer des informations (provenant d’utilisateurs non approuvés).

throw rejette l’exception capturée, en conservant la trace de la stack, tandis que throw new Exception perd certains des détails de l’exception interceptée.

Vous utiliseriez normalement throw par lui-même pour enregistrer une exception sans la traiter complètement à ce stade.

BlackWasp a un bon article intitulé Throwing Exceptions in C # .

Lancer une nouvelle exception élimine la trace de stack actuelle.

throw; conservera la trace de la stack d’origine et est presque toujours plus utile. L’exception à cette règle est lorsque vous souhaitez envelopper l’Exception dans une exception personnalisée de votre choix. Vous devriez alors faire:

 catch(Exception e) { throw new CustomException(customMessage, e); } 

throw est pour renvoyer une exception prise. Cela peut être utile si vous voulez faire quelque chose avec l’exception avant de la passer à la chaîne d’appels.

L’utilisation de throw sans aucun argument préserve la stack d’appels à des fins de débogage.

Un autre point que je n’ai vu personne:

Si vous ne faites rien dans votre bloc catch {}, essayer … catch est inutile. Je le vois tout le temps:

 try { //Code here } catch { throw; } 

Ou pire:

 try { //Code here } catch(Exception ex) { throw ex; } 

Pire encore:

 try { //Code here } catch(Exception ex) { throw new System.Exception(ex.Message); } 

Si vous le souhaitez, vous pouvez lancer une nouvelle exception, l’original étant défini comme une exception interne.

Votre deuxième exemple réinitialisera la trace de stack de l’exception. Le premier conserve le plus fidèlement les origines de l’exception. De plus, vous avez déballé le type d’origine qui est essentiel pour savoir ce qui a mal tourné … Si le second est requirejs pour la fonctionnalité – par exemple, append des informations étendues ou ré-envelopper avec un type spécial comme une “HandleableException” Assurez-vous que la propriété InnerException est également définie!

La différence la plus importante est que la deuxième expression efface le type d’exception. Et le type d’exception joue un rôle essentiel dans la capture des exceptions:

 public void MyMethod () { // both can throw IOException try { foo(); } catch { throw; } try { bar(); } catch(E) {throw new Exception(E.message); } } (...) try { MyMethod (); } catch (IOException ex) { Console.WriteLine ("Error with I/O"); // [1] } catch (Exception ex) { Console.WriteLine ("Other error"); // [2] } 

Si foo() lance une exception IOException , [1] catch block interceptera une exception. Mais lorsque bar() lance une Exception IOException , celle-ci sera convertie en plaine. Exception ant ne sera pas interceptée par le bloc catch [1] .

jeter ou lancer ex, les deux sont utilisés pour lancer ou relancer l’exception, lorsque vous connectez simplement les informations d’erreur et que vous ne voulez pas renvoyer d’informations à l’appelant, il vous suffit de consigner l’erreur dans catch et leave. Mais si vous voulez envoyer des informations significatives sur l’exception à l’appelant que vous utilisez ou lancez ex. Maintenant, la différence entre lancer et lancer est que jeter conserve la trace de la stack et d’autres informations, mais que lancer ex crée un nouvel object d’exception et que par conséquent la trace de la stack d’origine est perdue. Alors, quand devrions-nous utiliser jeter et lancer e, il existe encore quelques situations dans lesquelles vous pourriez vouloir relancer une exception, comme pour réinitialiser les informations de stack d’appel. Par exemple, si la méthode se trouve dans une bibliothèque et que vous souhaitez masquer les détails de la bibliothèque du code appelant, vous ne souhaitez pas nécessairement que la stack d’appels contienne des informations sur les méthodes privées de la bibliothèque. Dans ce cas, vous pouvez intercepter des exceptions dans les méthodes publiques de la bibliothèque, puis les renvoyer pour que la stack d’appels commence à ces méthodes publiques.

Jeter; Relancez l’exception d’origine et conservez le type d’exception.

Lancer une nouvelle exception (); Relancez le type d’exception d’origine et réinitialisez la trace de la stack d’exception

Jeter ex; Réinitialiser la trace de la stack d’exception et réinitialiser le type d’exception