Gestion des erreurs

publicité
Plan Présentation Les exceptions en Java Création Pratique
Plan Présentation Les exceptions en Java Création Pratique
Programmation
- Gestion des erreurs -
1
Présentation
Principe
Les exceptions
2
Les exceptions en Java
Principe et Types
Gestion et Syntaxe
Exemple
3
Création
Principe
Exemple
4
Pratique
Nicolas Malandain
March 15, 2005
as
as
Architecture des Systèmes d’Information
Gestion des erreurs
Plan Présentation Les exceptions en Java Création Pratique
Architecture des Systèmes d’Information
Gestion des erreurs
1 / 26
Principe Les exceptions
Plan Présentation Les exceptions en Java Création Pratique
La gestion d’erreur
2 / 26
Principe Les exceptions
Anciennes méthodes
Principe du code de retour
Une fonction retourne une valeur (code) indiquant si elle s’est bien
passée ou si il y a eu une erreur. Le code indique le type d’erreur.
La gestion d’erreur devrait/doit :
obliger le développeur à prendre en compte les erreurs importantes
Principe de la variable d’erreur globale
Une fonction, en cas d’erreur, affecte une valeur à une variable globale
(exemple : errno en C).
proposer au développeur de créer son propre jeu d’erreurs
permettre au développeur de gérer proprement les erreurs
Traitement des erreurs
Le traitement des erreurs est mélangé au code du programme
Gestion des erreurs
3 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 1
Gestion des erreurs
4 / 26
Plan Présentation Les exceptions en Java Création Pratique
Principe Les exceptions
Plan Présentation Les exceptions en Java Création Pratique
Les exceptions
Principe Les exceptions
Séparation du code et du traitement des erreurs
Sans gestion des exceptions
Définition
Une exception est un événement exceptionnel pouvant survenir lors de
l’exécution d’un programme, celle-ci interrompt alors le déroulement
normale du programme pour entrer dans une branche de traitement.
TypeCodeErreur lireFichier() {
TypeCodeErreur erreur = 0;
ouvrir le fichier;
if (fichier ouvert) {
obtenir sa taille;
if (tailleObtenu) {
allouer la mémoire;
if (mémoireDisponible) {
charger le fichier en mémoire;
if (erreurLecture)
erreur = 1;
} else
erreur = 2;
} else
erreur = 4;
}
fermer le fichier;
if (le fichier ne se ferme pas)
erreur = erreur and 8;
return erreur;
}
Avantages des exceptions
1
séparation du code et du traitement des erreurs
2
propagation des erreurs à travers la pile des appels
3
organisation des erreurs
Avec gestion des exceptions
lireFichier() {
try {
ouvrir le fichier;
obtenir sa taille;
allouer la mémoire;
charger le fichier en memoire;
fermer le fichier;
} catch (OuvertureFichierEchec) {
traiter l’erreur;
} catch(CalculTailleFichierEchec) {
traiter l’erreur;
} catch (AllocationMemoireEchec) {
traiter l’erreur;
} catch (LectureFichierEchec) {
traiter l’erreur;
} catch (fileCloseFailed) {
traiter l’erreur;
}
}
Exemple modifié issu du tutoriel Java de Sun
Gestion des erreurs
Plan Présentation Les exceptions en Java Création Pratique
Principe Les exceptions
Plan Présentation Les exceptions en Java Création Pratique
Propagation des erreurs
6 / 26
Principe Les exceptions
Organisation des erreurs
Sans gestion des exceptions
Avec gestion des exceptions
methode1() {
TypeCodeErreur erreur = methode2();
if (erreur)
traiter erreur;
else
code de la methode;
}
TypeCodeErreur methode2() {
TypeCodeErreur erreur;
erreur = methode3();
if (erreur)
return erreur;
else
code de la methode;
}
TypeCodeErreur methode3() {
TypeCodeErreur erreur;
erreur = lireFichier();
if (erreur)
return erreur;
else
code de la methode;
}
methode1() {
try {
methode2();
code de la methode;
} catch (exception) {
traiter erreur;
}
}
methode2() throws exception {
methode3();
code de la methode;
}
methode3() throws exception {
lireFichier();
code de la methode;
}
Gestion des erreurs
Gestion des erreurs
5 / 26
Objectif
soit traiter différemment les types d’erreurs
soit traiter de manière identique toutes les erreurs
Exemple modifié issu du tutoriel Java de Sun
7 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 2
Gestion des erreurs
8 / 26
Plan Présentation Les exceptions en Java Création Pratique
Principe et Types Gestion et Syntaxe Exemple
Plan Présentation Les exceptions en Java Création Pratique
Fonctionnement des Exceptions en Java
Hiérarchie
Principe
Lever une exception consiste à dérouter le flot d’instructions pour soit la
propager , soit la traiter.
Si l’exception est propagée au main alors le programme s’arrête et affiche
des informations la caractérisant.
Les exceptions sont des classes
Exceptions non controlées
java.lang.Error
problème de JVM ⇒ arrêt
java.lang.RuntimeException
gestion falcutative (ex: div / 0)
Informations associées à une exception levée
le type de l’exception
Utile au développeur qui appellera une méthode levant une
exception,
le bon type permettra le bon traitement
Exceptions controlées
java.lang.Exception
propagation/traitement obligatoire
le lieu de l’exception donné par la pile des appels
Utile au débogueur pour isoler/déboguer le problème
Deux méthodes pratiques de Throwable
void printStackTrace()
un message caractérisant l’exception
Utile à l’utilisateur pour l’informer
String toString()
Gestion des erreurs
Plan Présentation Les exceptions en Java Création Pratique
Principe et Types Gestion et Syntaxe Exemple
Gestion des erreurs
9 / 26
Principe et Types Gestion et Syntaxe Exemple
Plan Présentation Les exceptions en Java Création Pratique
10 / 26
Principe et Types Gestion et Syntaxe Exemple
Exemple d’exécution d’une exception non controlée
Propager des exceptions
DivisionParZero.java
Définition
Propager une exception consiste à renvoyer son traitement à la méthode
appelante.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package fr.insarouen.asi.prog.cours4;
import java.io.*;
public class DivisionParZero {
static int fct(int a, int b) {
return a/b;
}
public static void main(String[] param) {
int c;
c=fct(5,3);
System.out.println("c= "+c);
c=fct(3,0);
System.out.println("c= "+c);
}
}
Syntaxe
methode(...) throws Exception1, Exception2 {
...
// appel à une ou plusieurs méthodes susceptibles de lever des
// exceptions de classes Exception1, Exception2 (ou sous classes)
// la clause throws fait partie de la signature de la méthode
...
}
Exécution
java -classpath ./classes fr.insarouen.asi.prog.cours4.DivisionParZero
c= 1
Exception in thread "main" java.lang.ArithmeticException: / by zero
at fr.insarouen.asi.prog.cours4.DivisionParZero.fct(DivisionParZero.java:5)
at fr.insarouen.asi.prog.cours4.DivisionParZero.main(DivisionParZero.java:11)
Gestion des erreurs
Remarque
En Java, toute exception non contrôlé levée par une méthode est
implicitement propagée.
11 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 3
Gestion des erreurs
12 / 26
Plan Présentation Les exceptions en Java Création Pratique
Principe et Types Gestion et Syntaxe Exemple
Plan Présentation Les exceptions en Java Création Pratique
Principe et Types Gestion et Syntaxe Exemple
Attraper des exceptions (traitement)
Définition
Attraper une exception consiste à dérouter le flot d’instructions vers une
autre partie du programme permettant de la traiter (transfert de
contrôle).
Remarques
une seule clause catch exécutée (la première qui matche)
Syntaxe
methode(...) {
...
try {
// appel à une ou plusieurs méthodes susceptibles de lever des
// exceptions de classes Exception1, Exception2 (ou sous classes)
}
catch (Exception1 e) {
// Exception1 ne doit pas ^
etre anc^
etre de Exception2
}
catch (Exception2 e) {
possibilité d’attraper plusieurs exceptions en une seule clause avec
une classe mère.
}
finally {
// code toujours exécuté exception ou pas
}
...
la clause finally facultative est toujours exécutée
Utilisé pour exécuter des opérations coute que coute
ex: fermeture de fichiers, . . .
}
il est possible de mélanger propagation et traitement des exceptions
Gestion des erreurs
Plan Présentation Les exceptions en Java Création Pratique
Principe et Types Gestion et Syntaxe Exemple
Plan Présentation Les exceptions en Java Création Pratique
Lever des exceptions
14 / 26
Principe et Types Gestion et Syntaxe Exemple
TableauEntierNaturelDynamique.java
package fr.insarouen.asi.prog.cours4;
public class TableauEntierNaturelDynamique {
private int[] tab;
public TableauEntierNaturelDynamique(int tailledebase) {
tab=new int[tailledebase];
}
public int getEntier(int indice) {
if (indice < 0 || indice >= tab.length)
throw new IndexOutOfBoundsException("indice non valide");
return tab[indice];
}
public void setEntier(int indice, int valeur)
throws IndexOutOfBoundsException, IllegalArgumentException {
// runtime exception donc déclaration facultative
if (valeur < 0)
throw new IllegalArgumentException("Entier < 0");
try {
tab[indice]=valeur;
}
catch (IndexOutOfBoundsException e) {
if (indice < 0)
throw new IndexOutOfBoundsException("indice < 0");
int [] tabtmp=new int[indice+1];
System.arraycopy(tab, 0, tabtmp, 0, tab.length);
tabtmp[indice]=valeur;
tab=tabtmp;
}
}
...
}
Définition
Lever une exception consiste à dérouter le flot d’instructions du
programme pour la traiter ou la propager.
Syntaxe
methode(...) ... {
...
throw new UneException();
...
}
Gestion des erreurs
Gestion des erreurs
13 / 26
15 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 4
Gestion des erreurs
16 / 26
Plan Présentation Les exceptions en Java Création Pratique
Principe Exemple
Plan Présentation Les exceptions en Java Création Pratique
Principes et Syntaxe
Principe Exemple
Reprise du TableauEntierNaturelDynamique
La hiérarchie d’exceptions créée
Utilisation
créer son propre système d’erreurs
traduire des exceptions de “trop bas niveau”
Syntaxe
Les exceptions sont des classes comme les autres. Les nouvelles
exceptions doivent dérivées de Exception ou de RuntimeException
Gestion des erreurs
Plan Présentation Les exceptions en Java Création Pratique
17 / 26
Principe Exemple
Plan Présentation Les exceptions en Java Création Pratique
18 / 26
Principe Exemple
TableauEntierNaturelDynamiqueAvecException.java. . .
TableauEntierNaturelDynamiqueException.java
package fr.insarouen.asi.prog.cours4;
public class TableauEntierNaturelDynamiqueAvecException {
...
public int getEntier(int indice) throws TableauIndiceHorsBornesException {
if (indice < 0 )
throw new TableauIndiceNegatifException("indice:"+indice+" < 0 interdit");
if (indice >= tab.length )
throw new TableauIndiceHorsBornesException("indice supérieur ou égal à la borne supérieure");
return tab[indice];
}
public void setEntier(int indice, int valeur)
throws TableauEntierValeurNegativeException, TableauIndiceNegatifException {
if (valeur < 0)
throw new TableauEntierValeurNegativeException(valeur+" < 0");
try {
tab[indice]=valeur;
}
catch (IndexOutOfBoundsException e) {
if (indice < 0)
throw new TableauIndiceNegatifException(indice+" < 0");
int [] tabtmp=new int[indice+1];
System.arraycopy(tab, 0, tabtmp, 0, tab.length);
tabtmp[indice]=valeur;
tab=tabtmp;
}
}
...
package fr.insarouen.asi.prog.cours4;
public class TableauEntierNonTrouveException
extends TableauEntierNaturelDynamiqueException {
public TableauEntierNonTrouveException(String s) {
super(s);
}
public TableauEntierNonTrouveException() {
}
}
TableauIndiceHorsBornesException.java
package fr.insarouen.asi.prog.cours4;
public class TableauIndiceHorsBornesException
extends TableauEntierNaturelDynamiqueException {
public TableauIndiceHorsBornesException(String s) {
super(s);
}
public TableauIndiceHorsBornesException() {
}
}
...
Gestion des erreurs
Gestion des erreurs
19 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 5
Gestion des erreurs
20 / 26
Plan Présentation Les exceptions en Java Création Pratique
Principe Exemple
Plan Présentation Les exceptions en Java Création Pratique
Cohérence
TableauEntierNaturelDynamiqueAvecException.java
(suite)
public int chercherEntier(int valeur)
throws TableauEntierNonTrouveException, TableauEntierValeurNegativeException {
if (valeur < 0)
throw new TableauEntierValeurNegativeException(valeur+" < 0");
if (tab.length == 0)
throw new TableauEntierVideException("Tableau vide");
for (int i=0; i<tab.length; i++)
if (tab[i] == valeur )
return i;
throw new TableauEntierNonTrouveException(valeur+" non trouvé");
Ce qu’il faut faire
Le contenu d’un bloc try/catch doit être “cohérent”
essayer de regrouper un ensemble d’instructions liées
toujours traiter l’erreur dans le catch, cad pas de clause catch vide
lors d’un throws toujours se mettre du point de vue de l’appelant
(méthode ou utilisateur) et non de celui de la classe.
quel exception peut il comprendre ? a-t-il la possibilité de la traiter ?
}
envoyer plus de 3 types d’exceptions n’est pas très bon
la méthode fait trop de choses → la découper
public String toString() {
StringBuilder sb=new StringBuilder();
for (int i=0; i<tab.length; i++) {
sb.append(tab[i]);
if (i!=tab.length-1)
sb.append("/");
}
return sb.toString();
}
...
Gestion des erreurs
le changement de signature est problématique → mettre à jour tout
le code
bien spécifier dès le départ et/ou créer une hiérarchie d’exceptions et
ne déclarer que la classe mère dans le throws
21 / 26
Plan Présentation Les exceptions en Java Création Pratique
Gestion des erreurs
Plan Présentation Les exceptions en Java Création Pratique
Problème exception perdue
Chaı̂nage d’exceptions
ExceptionPerdue.java
Principe
Une exception levée est attrapée puis aussitôt une exception d’un autre
type est lancée
package fr.insarouen.asi.prog.cours4;
public class ExceptionPerdue {
public static void main(String[] args) throws Exception {
MessageInTheBottle mp = new MessageInTheBottle();
try {
mp.lanceExceptionPerdue();
}
finally {
mp.lanceExceptionQuiCache();
}
}
}
class MessageInTheBottle {
void lanceExceptionPerdue() throws PerdueException {
throw new PerdueException();
}
void lanceExceptionQuiCache() throws QuiCacheException {
throw new QuiCacheException();
}
}
...
Exemple d’utilisation
Une classe a besoin de charger une ressource quelconque
plusieurs possibilités pour obtenir la ressource : BD, fichier, URL,
...
donc plusieurs exceptions possibles : ⇒ SQLException,
FileNotFoundException, MalformedURLException, ...
toutes attrapées et lancement d’une exception commune
adapté de “Thinking in Java”
Gestion des erreurs
22 / 26
Problème : Perte de la cause initiale de l’exception
Solution : depuis le JDK 1.4 le chaı̂nage d’exceptions est pris en compte
dans Throwable
23 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 6
Gestion des erreurs
24 / 26
Plan Présentation Les exceptions en Java Création Pratique
Plan Présentation Les exceptions en Java Création Pratique
Exemple de chaı̂nage d’exceptions
ExempleChainageException.java
package fr.insarouen.asi.prog.cours4;
import java.io.*;
import java.net.*;
VecteursNoms.java
package fr.insarouen.asi.prog.cours4;
import java.io.*;
import java.net.*;
public class VecteurNoms {
public void chargerNoms(File fichier) throws ChargementRessourceException {
try {
FileReader reader = new FileReader(fichier);
// code
}
catch (IOException e) {
throw new ChargementRessourceException("Problème de chargement du fichier :"
+fichier,e);
}
}
public void chargerNoms(URL url) throws ChargementRessourceException {
try {
URLConnection connection = url.openConnection();
Object obj = connection.getContent();
// code
}
catch (IOException e) {
throw new ChargementRessourceException("Problème de chargement de l’URL :"+url,e);
}
}
}
Gestion des erreurs
public class ExempleChainageException {
public static void main(String[] args) throws Exception {
VecteurNoms vn = new VecteurNoms();
vn.chargerNoms(new URL("http://asi.insa-rouen.fr/"));
vn.chargerNoms(new File("/tmp/unfichierquinexistepas"));
}
}
Résultat
Exception in thread "main" fr.insarouen.asi.prog.cours4.ChargementRessourceException:
Problème de chargement du fichier :/tmp/unfichierquinexistepas
at fr.insarouen.asi.prog.cours4.VecteurNoms.chargerNoms(VecteurNoms.java:14)
at fr.insarouen.asi.prog.cours4.ExempleChainageException.main(
ExempleChainageException.java:12)
Caused by: java.io.FileNotFoundException: /tmp/unfichierquinexistepas (No suchfile or
directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileReader.<init>(FileReader.java:55)
at fr.insarouen.asi.prog.cours4.VecteurNoms.chargerNoms(VecteurNoms.java:10)
... 1 more
25 / 26
cm04-gestiondeserreurs.pdf — March 15, 2005 — 7
Gestion des erreurs
26 / 26
Téléchargement