Voici le code:
public Response getABC(Request request) throws Exception {
Response res = new Response();
try {
if (request.someProperty == 1) {
// business logic
} else {
throw new Exception("xxxx");
}
} catch (Exception e) {
res.setMessage(e.getMessage); // I think this is weird
}
return res;
}
Ce programme fonctionne bien. Je pense qu'il devrait être repensé, mais comment?
Cela n'a aucun sens de lancer une exception dans un bloc try et de l'attraper immédiatement, à moins que le bloc catch ne lance une exception différente.
Votre code aurait plus de sens de cette façon:
public Response getABC(Request request) {
Response res = new Response();
if (request.someProperty == 1) {
// business logic
} else {
res.setMessage("xxxx");
}
return res;
}
Vous n'avez besoin du bloc try-catch que si votre logique métier (exécutée lorsque la condition est true
) peut générer des exceptions.
Si vous n'acceptez pas l'exception (ce qui signifie que l'appelant devra la gérer), vous pouvez vous passer de la clause else
:
public Response getABC(Request request) throws Exception {
if (request.someProperty != 1) {
throw new Exception("xxxx");
}
Response res = new Response();
// business logic
return res;
}
si vous lancez l'exception de la méthode, alors pourquoi se donner la peine de l'attraper? vous pouvez soit renvoyer une réponse avec le message "xxxx", soit émettre une exception permettant à l'appelant de cette méthode de la gérer.
public Response getABC(Request requst) {
Response res = new Response();
if(request.someProperty == 1){
//business logic
else{
res.setMessage("xxxx");
}
}
return res;
}
OR
public Response getABC(Request requst) throw Excetpions {
Response res = new Response();
if(request.someProperty == 1){
//business logic
else{
throw new Exception("xxxx");
}
return res;
}
public void someMethod(Request request) {
try {
Response r = getABC(request);
} catch (Exception e) {
//LOG exception or return response with error message
Response response = new Response();
response.setMessage("xxxx");
retunr response;
}
}
ça ne semble pas juste quand on lance exprès une exception et qu'on l'attrape directement, ça peut être refait comme ça,
peut changer throw new Exception("xxxx");
avec res.setMessage("xxxx");
,
et peut ensuite conserver la partie exception d’exception afin d’attraper l’exception pouvant se produire dans la logique métier.
public Response getABC(Request requst) {
Response res = new Response();
try{
if(request.someProperty == 1){
//business logic
else{
res.setMessage("xxxx");
}
}catch(Exception e){
res.setMessage(e.getMessage);
}
return res;
}
Je pense que vous pourriez manquer le point de cet essai/attraper. Le code utilise le système des exceptions pour masquer tout message d’exception à l’appelant. Cela pourrait être profondément dans une pile d'appels imbriqués - pas seulement celui "jette" que vous regardez.
En d'autres termes, la déclaration "throws" dans votre exemple de code tire parti de ce mécanisme pour transmettre un message au client, mais ce n'est certainement pas l'utilisateur principal prévu de try/catch. (En outre, c'est un moyen bâclé et peu coûteux de transmettre ce message - cela peut semer la confusion.)
Cette valeur de retour n’est de toute façon pas une bonne idée car Exceptions n’a souvent pas de message et peut être reformaté ... c’est mieux que rien. Les messages d'exception ne sont tout simplement pas le meilleur outil pour cela, mais la gestion d'une exception à un niveau aussi élevé est toujours une bonne idée.
Si vous refactorisez ce code, assurez-vous de rechercher les exceptions d’exécution pouvant être émises n'importe où dans votre base de code (du moins appelées pendant le traitement du message) - et même dans ce cas, vous devriez probablement conserver le message catch/return en tant que catch-all juste au cas où une exception d'exécution apparaît que vous ne vous attendiez pas. Vous n'avez pas à renvoyer l'erreur "Message" en tant que message de votre réponse. Il pourrait s'agir d'une erreur "Nous ne pouvons pas traiter votre demande pour l'instant", mais veillez à vider la trace de la pile dans un journal. . Vous êtes en train de le jeter.
Tout d’abord, agissez avec plus de soin lorsque vous refactorisez une méthode de travail, surtout si vous effectuez une refactorisation manuelle. Cela dit, introduire une variable pour tenir message
peut être un moyen de changer le design:
public Response getABC(Request requst) throw Excetpions {
String message = "";
try{
if(request.someProperty == 1){
//business logic
else{
message = "xxxx";
}
}catch(Exception e){
message = e.getMessage();
}
Response res = new Response();
res.setMessage(message);
return res;
}
L'hypothèse est que le business logic
fait son propre retour quand il réussit.
Pourquoi avez-vous utilisé l'instruction try/catch alors que vous avez déjà lancé Checked Exception ?
L'exception vérifiée est généralement utilisée dans certains langages tels que C++ ou Java, mais pas dans les nouveaux langages tels que Kotlin. Personnellement, je limite à l'utiliser.
Par exemple, j'ai un cours comme celui-ci:
class ApiService{
Response getSomething() throw Exception();
}
qui se sent propre et lisible, mais mine l'utilité du mécanisme de traitement des exceptions. Pratiquement, getSomething()
ne déclenche pas une exception vérifiée mais doit quand même se comporter comme il le fait? Cela fonctionne quand il y a quelqu'un en amont d'ApiService qui sait comment traiter l'imprévisible ou inévitable des erreurs comme celle-ci. Et si vous savez vraiment comment vous en occuper, continuez et utilisez un exemple similaire à l'exemple ci-dessous, sinon, Une exception non vérifiée serait suffisante.
public Response getSomething(Request req) throws Exception{
if (req.someProperty == 1) {
Response res = new Response();
// logic
} else {
thows Exception("Some messages go here")
}
}
Je vais encourager à faire de cette façon:
public Response getSomething(Request req){
if (req.someProperty == 1) {
Response res = new Response();
// logic
return res;
} else {
return ErrorResponse("error message"); // or throw RuntimeException here if you want to
}
}
Pour plus d'informations, Kotlin
dont j'ai déjà parlé ne supporte pas Exception contrôlée pour plusieurs raisons.
Voici un exemple d'interface de la classe JDK
implémentée par la classe StringBuilder
:
Appendable append(CharSequence csq) throws IOException;
Que dit cette signature? Il dit que chaque fois que j'ajoute une chaîne à quelque chose (un StringBuilder
, une sorte de journal, une console, etc.), je dois attraper ces IOExceptions
. Pourquoi? Parce qu'il peut être en train de jouer IO
(Writer implémente également Appendable
)… Donc, il en résulte ce genre de code partout:
try {
log.append(message)
}
catch (IOException e) {
// Must be safe
}
Et ce n’est pas bon, voir Effective Java, 3e édition, article 77: Ne pas ignorer les exceptions.
Jetez un coup d'oeil à ces liens:
Le mécanisme d'exception a trois objectifs:
C’est beaucoup de fonctionnalités pour un mécanisme. Afin de garder les programmes aussi simples que possible - pour les futurs responsables - nous ne devrions donc utiliser ce mécanisme que si nous vraiment devons le faire.
Dans votre exemple de code, je m'attendrais à ce que toute instruction throw
soit très sérieuse, indiquant que quelque chose ne va pas et que le code est censé gérer cette urgence quelque part. J'aurais besoin de comprendre ce qui n'allait pas et la gravité de la situation avant de continuer à lire le reste du programme. Ici, c’est juste un retour fantaisiste d’une Corde, et je me gratterais la tête en me demandant "Pourquoi était-ce nécessaire?" et cet effort supplémentaire aurait pu être mieux dépensé.
Ce code n’est donc pas aussi bon que possible, mais je ne le changerais que si vous aviez le temps de faire un test complet. Changer le déroulement du programme peut introduire des erreurs subtiles et vous devez avoir les changements à l’esprit si vous devez réparer quelque chose.
Idem si vous souhaitez que le message d’exception spécifique soit renvoyé par la JVM en cas d’erreur, vous pouvez utiliser la méthode try-catch avec les méthodes getMessage () ou printStackTrace () dans le bloc catch. Donc ici vous pouvez modifier votre code comme:
public Response getABC(Request request) throws Exception {
Response res = new Response();
try {
if (request.someProperty == 1) {
// business logic
}
} catch (Exception e) {
res.setMessage(e.getMessage);
}
return res;
}