Vous êtes sur la page 1sur 39

Exceptions

Quest-ce quune exception ?


Une exception est une erreur ou bien une action inattendue qui se produit durant lexcution dun programme Une exception se traduit par un signal qui interrompt le droulement normal dun programme

Intrt
Contrler le droulement des calculs en localisant des vnements exceptionnels pour :
Traiter des erreurs Arrter un calcul

Rendre plus lisible et plus structur le texte dune unit en sparant traitement du cas gnral et traitement des cas exceptionnels
3

Point de vue thorique


On peut assimiler un programme au calcul dune fonction en mathmatiques Tout programme tablit une correspondance entre un domaine (les donnes du programme) et un co-domaine (les rsultats) De fait, les programmes ne traduisent que des fonctions totales (partout dfinies) Rien interdit un programme de sexcuter sur des donnes particulires pour lesquelles la fonction nest pas dfinie (ex: division par zro)
4

Vers des programmes robustes


Le mcanisme des exceptions dans les LP (Ada, C++, Java) permet de prendre en compte le cas des donnes exceptionnelles (inattendues) de manire construire des programmes robustes Par exemple, lorsquun programme demande lutilisateur de saisir des donnes numriques dans un certain intervalle, il doit (pour tre robuste) dterminer si elles sont numriques et si elles appartiennent lintervalle. Dans le cas contraire, il peut prvoir une action spcifique; par exemple, demander une nouvelle saisie.
5

Gestion traditionnelle des cas derreur


La manire traditionnelle de prendre en compte les cas derreur est dutiliser les structures de contrle classiques Exemple : supposons quAda ne traite pas les exceptions. La procdure get devrait possder un paramtre reprsentant lerreur ventuelle
procedure get(X:out String;C:out Integer)
6

Lecture dune chane de caractres


declare A:String(1..10); code:Integer; begin get(A,code); case code is when 1=> caractre numrique when +1=> la chane lue ne possde pas 10 caractres when others=> lecture OK end case; end;

Inconvnients
Le code de gestion de erreurs se mlange au code normal Ajout de paramtres non applicatifs aux procdures (le paramtre code) Surplus de code (case) Risque de propagation des erreurs => prolifration des paramtres supplmentaires
8

Exceptions prdfinies
Elles sont prsentes dans lenvironnement initial et dclenches (leves) :
En cas de manque despace mmoire (STORAGE_ERROR) En cas de tentative de violation dune structure de contrle ou dappel dune procdure non encore labore (PROGRAM_ERROR) Si la valeur dune expression dpasse les bornes de lensemble des valeurs possibles (CONSTRAINT_ERROR)

Exception prdfinie : exemple


with Ada.Text_io; with Ada.Integer_Text_io; use Ada.Text_io; use Ada.Integer_Text_io; procedure divparzero is res,num,den:Integer; begin put("numrateur : ");get(num); put("dnominateur : ");get(den); res:=num/den; put("rsultat=");put(res); new_line;
end divparzero;
10

Exception prdfinie : suite


Si la valeur saisie pour le dnominateur est 0:
Le programme ne termine pas son excution (plantage) Lexception prdfinie CONSTRAINT_ERROR est leve Le message :
raised CONSTRAINT_ERROR : divparzero.adb:11

est affich
11

Dclaration
Syntaxe
<dclaration_exception>::= <identificateur_exception>:exception;

Smantique
Lidentificateur est introduit dans lenvironnement de ltat courant

Exemple
erreur,divparzero:exception;

12

Type exception
Lensemble des valeurs du type exception est lensemble des signaux nomms

La seule opration sur les exceptions est :


la leve (dclenchement)

13

Leve dune exception


Lever une exception dans le code dun programme cest signaler quune situation anormale est dtecte Syntaxe
<leve_exception>::= raise <identificateur_exception>

Smantique
Lexcution de linstruction raise interrompt le droulement normal du programme et transfert le contrle un traitement de cette exception
14

Quel traitement ?
Le traitement dune exception peut :
tre prdfini (cas des exceptions prdfinies) tre cod par le programmeur

consister en une propagation du signal vers les units appelantes


15

Leve dune exception : exemple(1)


with Ada.Text_io; use Ada.Text_io; with Ada.Characters.Handling; use Ada.Characters.Handling;
-- saise d'une chaine de caractres alphabtiques procedure saisie_alpha is ligne:String(1..80); lg:Natural; non_alpha:exception; begin

16

Leve dune exception : exemple(2)


put("entrer une chaine : "); get_line(ligne,lg); declare chaine:String(1..lg):=ligne(1..lg); begin for i in chaine'range loop if is_digit(chaine(i)) then raise non_alpha; end if; end loop; end; end saisie_alpha;
17

Leve dune exception : exemple(3)


Pour la donne saisie
Nestor Martin

le rsultat est :
Nestor Martin

Pour la donne
Nest0r Mart1

le rsultat est :
raised SAISIE_ALPHA.NON_ALPHA:saisie_alpha.adb:18
18

Rcupration dune exception (1)


Rcuprer une exception, cest se donner la possibilit dassocier un traitement particulier la situation dtecte Permet de prvenir une interruption brutale du programme en prvoyant un mode de fonctionnement dgrad ou de substitution

19

Rcupration dune exception : syntaxe


Syntaxe
<rcupration_exception>::= exception when <identificateur_exception>=><traitement>; [when <identificateur_exception>=><traitement>;] [when others=><traitement>;]

La partie exception constitue la partie optionnelle dun bloc :


declare begin exception end;
20

Rcupration dune exception : smantique


Les identificateurs dexception servent de filtre pour lexcution des traitements Ils doivent donc tre prsents dans lenvironnement de rcupration Le filtre universel others permet de filtrer toutes les exceptions prsentes ou non dans lenvironnement
21

Rcupration dune exception : exemple 1


function demain(X:Jour) return Jour is begin return Jour'succ(X); exception when CONSTRAINT_ERROR=> return Jour'first; end demain;

22

Rcupration dune exception : exemple 2


declare chaine:String(1..lg):=ligne(1..lg); begin for i in chaine'range loop if is_digit(chaine(i)) then raise non_alpha; end if; end loop; put_line(chaine); exception when non_alpha=> put ("certains caracteres saisis sont numriques"); new_line; end;
23

Rcupration dune exception : exemple 2 (suite)


Pour la donne saisie
Nestor Martin

le rsultat est :
Nestor Martin

Pour la donne
Nest0r Mart1

le rsultat est :
certains caracteres saisis sont numriques

24

Porte des exceptions


Une exception est connue par son nom dans son unit de dclaration ainsi que dans toutes les units englobes Si une exception est leve dans une unit, le traitement est interrompu et le contrle est transfr au traitant dexception Si lexception nest pas traite dans cette mme unit, alors elle est propage vers le traitant dexception de lunit appelante et ainsi de suite vers lunit principale jusqu lexcutif Ada.
25

declare erreur:exception; procedure B is begin raise erreur; end B; procedure C is begin B; exception when erreur=>traitement_erreur_C;raise; end C; procedure A is begin C; exception when erreur=>traitement_erreur_A; end A; begin A; end;

26

Propagation dune exception en dehors de sa porte


Lorsquune exception nest pas traite dans son unit de dclaration, elle est propage vers son unit appelante => elle se retrouve en dehors de sa porte Pour tre traite, elle doit alors tre filtre par le filtre universel others

27

procedure recupere is procedure declenche is exception_locale:exception;

begin
raise exception_locale; end declenche; begin declenche; exception when others=> traitement de toutes les exceptions; end recupere;

28

Exception dans une dclaration


Si une exception est dclenche dans une dclaration, elle est propage vers lunit appelante Dans lexemple qui suit, le rsultat affich sera :
recupere externe

29

declare ex:exception; function declenche return Integer is begin raise ex; end declenche; begin declare X:Integer:=declenche; begin put("interne"); exception when ex=>put("recupere interne"); end; exception when ex=>put("recupere externe"); end;
30

Exception leve dans un traitant dexception


Une exception leve dans un traitant dexception est propage vers lunit appelante Pour un traitement couche par couche de lexception, on peut propager la mme exception en la levant de nouveau par raise; Lorsque plusieurs exceptions sont filtres par others, il ny a pas moyen de nommer explicitement lexception survenue. Dans ce cas, il est possible de la lever de nouveau par raise;
31

declare begin declare X:Integer; begin declare ex2,ex1:exception; begin get(X); if X=0 then raise ex1; else raise ex2 end if; exception when ex2=>put("traitement ex2");raise; when ex1=>put("traitement ex1");raise; end; exception when others=>put("traitement complmentaire de ex1 si X=0"); put("ou traitement complmentaire de ex2 si x/=0");raise; end; exception when others=>put("traitement complmentaire de ex1 si X=0"); put("ou traitement complmentaire de ex2 si x/=0"); 32 end;

Exception : utilisation
Pour viter un plantage
declare N:Integer; begin loop begin get(N);exit; exception when DATA_ERROR=>skip_line;put_line("recommencez!"); end; end loop; end;
33

Exemple dtaill (1)


Ralisation dun programme de login sur une machine hte.
Le programme affiche tout dabord linvite :
login:

Lutilisateur tape alors son nom dutilisateur


Si ce nom est inconnu du systme, la tentative est arrte, lexception login_errone est leve et propage

34

Exemple dtaill (2)


Si le nom est connu du systme, le programme affiche : passwd: et lutilisateur est invit taper son mot de passe.
Si le mot de passe est correct, cest termin, sinon le programme imprime un message ad hoc et lutilisateur doit retaper son mot de passe. Lutilisateur a trois essais, la suite desquels lexception login_errone est leve et propage
35

Exemple dtaill (3)


On suppose que les procdures suivantes appartiennent lenvironnement du programme de login :
procedure teste_nom(N:in String); -- vrifie que N est connu du systme -- si ce nest pas le cas, lexception -- nom_errone est leve procedure teste_mot_de_passe (M:in String;N:in String); -- vrifie que M est connu et associ N -- sinon lexception mot_errone est leve
36

with Ada.Text_io; use Ada.Text_io; with Test;use Test; procedure login is nom,mot:String(1..8); begin put("login: ");get(nom);teste_nom(nom); put_line(nom);put("passwd: ");

for i in 1..3 loop


get(mot);teste_mot_de_passe(nom,mot); exit; end loop; end login;

37

with Ada.Text_io; use Ada.Text_io;


with Test;use Test; procedure login is nom,mot:String(1..8);

begin
put("login: ");get(nom);teste_nom(nom); put_line(nom);put("passwd: "); for i in 1..3 loop begin get(mot);teste_mot_de_passe(nom,mot); exit; exception -- suite page suivante
38

when mot_errone => put("mot de passe errone"); if i<3 then put("Essayez encore"); else raise; end if; end; end loop; exception when nom_errone => put("nom"&nom&" inconnu"); put("login interrompu"); raise login_errone; when mot_errone => raise login_errone; end login;
39