Question

Dans certains codes Delphi 7 que je maintiens, j'ai remarqué de nombreuses instances parmi les suivantes:

with ADOQuery1 do begin
  // .. fill out sql.text, etc
  try
    execSQL;
  except
    raise;
  end;
end;

Il me semble que ces blocs d’essai pourraient être supprimés car ils ne font rien. Cependant, je me méfie des éventuels effets secondaires subtils.

Quelqu'un peut-il penser à des situations dans lesquelles ces blocs pourraient réellement faire quelque chose qui ne se produirait pas sans eux?

Était-ce utile?

La solution

Dans ce contexte, l'opération de relance n'a aucun effet et doit être supprimée car elle ne fait que relancer l'exception que le bloc d'exception vient de capturer. Le paramètre raise est généralement utilisé pour transférer le contrôle à la fin du bloc lorsqu'aucune gestion d'erreur appropriée n'est disponible. Dans ce qui suit, nous traitons l’exception personnalisée, mais toute autre exception doit être gérée ailleurs.

try
  someOperation;
except
  on e: ECustomException do
    SomeCustomHandelr;
  else
     begin
       // the raise is only useful to rethrow the exception to an encompasing 
       // handler.  In this case after I have called my logger code. as Rob
       // mentioned this can be omitted if you arent handling anything because
       // the compiler will simply jump you to the next block if there is no
       // else.
       LogUnexpectedException('some operation failed',e);
       raise;
     end;
end;

Veillez à ce qu'il existe un formulaire similaire sans l'option "augmenter". Cela a pour effet secondaire de manger / cacher toute exception. pratiques de développeurs très peu scrupuleux qui, espérons-le, sont passés à la concurrence.

with ADOQuery1 do begin  
  // .. fill out sql.text, etc  
  try    
    execSQL; 
  except
    // no handler so this just eats any "errors"    
  end;

Autres conseils

Supprimer le code d'exception de l'extrait de code ci-dessus ne fera aucune différence. Vous pouvez (et je pense que vous devriez car cela réduit la lisibilité) pour le supprimer.

D'accord, vraiment deux questions ici.

Tout d’abord, il a un sens : si execSQL lève une exception, il est attrapé par le bloc try et transmis à l’exception. Ensuite, il est transféré par la relance au bloc immédiatement supérieur.

Deuxièmement, est-ce utile ? Probablement pas. C’est presque certainement le résultat de l’une des trois choses suivantes:

  1. Une personne aux cheveux pointus a écrit une norme de codage dans laquelle il est indiqué que "toutes les opérations pouvant générer une exception doivent figurer dans un bloc try".
  2. Quelqu'un voulait revenir et transformer les exceptions générées par la déclaration execSQL en une autre exception plus significative,
  3. .
  4. Quelqu'un de nouveau ne savait pas que ce qu'il avait écrit était isomorphe: laisser l'environnement ultime se soucier de l'exception, et a donc pensé qu'il devait la transmettre.

J'ai peut-être répondu un peu vite, voir à la fin ...
Comme c'est le cas, il est inutile pour l'application .
Période!

Maintenant sur le " pourquoi " côté. Il peut s’avérer nécessaire de normaliser la gestion des exceptions s’il existait / était / sera / sera dans d’autres endroits / une sorte de code de journalisation inséré avant la relance:

  try
    execSQL;
  except
    // Log Exception..
    on E: Exception do
    begin
      LogTrace(Format('%s: Exception Message[%s]',[methodname, E.Message]));
      raise;
    end;
  end;

ou pour le code de nettoyage:

  try
    execSQL;
  except
    //some FreeAndNil..
    raise;
  end;

Mise à jour : il y aurait un cas où je verrais une utilisation telle qu'elle est ...
... pour pouvoir placer un point d'arrêt sur la ligne augmenter , pour avoir une chance de voir ce qui se passe dans le contexte de ce bloc de code.

Ce code ne fait rien, sauf pour permettre au programmeur d'origine de placer un point d'arrêt sur le 'Raise' et de voir l'exception se rapprocher de la cause possible dans le source. En ce sens, il s’agit d’une technique de débogage parfaitement raisonnable.

En fait, je devrais poster cela en tant que commentaire dans les réponses de François, mais je ne sais pas s'il est possible d'insérer du code formaté ici :( Je poste donc ceci en tant que réponse.

2mghie:

  
    
      

Le second est complètement unidiomatique, on utiliserait finalement à la place.

    
  

Non, "finalement" va nettoyer l'objet toujours. " Sauf " - seulement à l'exception. Prenons le cas de function, qui crée, remplit et renvoie un objet:

function CreateObj: TSomeObj;
begin
  Result := TSomeObj.Create;
  try
    ... // do something with Result: load data, fill props, etc.
  except
    FreeAndNil(Result); // oops: bad things happened. Free object to avoid leak.
    raise;
  end;
end;

Si vous mettez "enfin" là - la fonction retournera nil toujours. Si vous omettez " essayez " bloquer - il y aura une fuite de ressources en cas d'exception dans "...".

P.S. Bien sûr, vous pouvez utiliser " enfin " et vérifiez ExceptObj, mais ... n'est-ce pas moche?

Le titre contient une question assez large, tandis que son explication donne un exemple plus spécifique. Donc, ma réponse à la question de savoir comment on procède à partir de l'exemple peut certainement ajouter quelque chose d'utile à ce qui a déjà été dit ici.

Mais peut-être peut-être que Blorgbeard veut savoir si du tout a du sens pour try ... sauf raise; fin . Dans Delphi 7, si je me souviens bien, Exit déclenchera la partie finally d'un bloc try-finally (comme si c'était une sorte de exception). Quelqu'un pourrait considérer ce comportement comme inapproprié pour leur travail, et l’utilisation de la construction en question est tout à fait une solution de contournement.

Seulement, il serait toujours étrange d'utiliser une seule raise; , mais nous aurions alors dû parler de utilité plutôt que de signification , comme Charlie l'a soigneusement observé.

Ce code ne fait rien sauf relancer une exception qui sera déjà levée sans cet essai sauf bloc. Vous pouvez l'enlever en toute sécurité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top