HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Hibakezelés a Delphi-ben


Hibakezelés 1. rész

Példaprogram letöltése

8296 bájt

Most induló cikksorozatunkban azt vizsgáljuk meg részletesen, hogy milyen eszközök, lehetőségek állnak rendelkezésünkre, hogy programunk működése során fellépő hibákat kezeljük, elkerüljük.
Amikor Delphi alól futtatjuk a programunkat és abban hiba történik, akkor programunk futása felfüggesztésre kerül és a Delphi lesz ismét az aktív. Ekkor - ha a hiba saját forráskódjainkban van - a Delphi automatikusan arra a sorra áll a forráskódban, ahol a hiba történt.

Ezek után, ha a hiba jellege ezt lehetővé teszi, akkor az F9 lenyomásával tovább futtathatjuk. Ekkor megjelenik a programunkban is egy kis dialóg ablakban az iménti hiba. Ha nem Delphi alól futtatnánk a programot, akkor csak ez az utóbbi kis dialóg jelezné a hibát, ami feltehetőleg egy angol nyelvű üzenet lenne, ami nem sokat mondana a felhasználónak. Az alábbiakban majd arra is láthatunk példát, hogy miként tudjuk lekezelni a hibákat úgy, hogy ne a Delphi alapértelmezett, angol nyelvű hibaüzenetei jelenjenek meg, hanem a sajátjaink.

Mellékelt példa kipróbálásához célszerű kikapcsolni azt a lehetőséget, hogy hiba esetén a Delphi mutassa meg, hogy melyik forráskód részletnél történt az.

Ehhez a Tools - Debugger Options menüpont kiválasztása után megjelenő dialóg ablakban a Language Exceptions lapon a Stop on Delphi Exceptions CheckBox-ot kapcsolja ki.
Delphi 3 esetén ez a lehetőséget a Tools - Environment options menüpont kiválasztásával a Preferences lapon a Break on exception nevű CheckBox takarja.

Mellékelt példában öt nyomógomb szerepel, melynek lenyomásakor olyan kód fut le, mely hibát okoz. Nézzük ezeket sorra.

Az első gomb esetében megpróbálunk nullával osztani, ami nem valószínű, hogy sikerül. Mivel nem foglalkozunk a forráskódban a hibakezeléssel, így a Delphi saját hibakezelő rutinja fut, mely egy kis dialóg ablakban megjeleníti a Floating point division by zero üzenetet. Ezt az ablakot bezárva a programunk futása folytatódhat.
procedure TForm1.Button1Click(Sender: TObject);
var
  a, b, c: double;
begin
  a:=10;
  b:=0;
  c:=a/b;
  Label1.Caption:=Format('%g', [c]);
end;

Nézzük most, hogy miként tudjuk kijátszani a Delphi saját hibakezelő rutinját és egy saját hibaüzenetet megjeleníteni. Ehhez a try-except-en kulcsszavakat kell használnunk. Ez hasonlít az if-else-end működéséhez. Lényege, hogy a try és az except kulcsszavak közé írt forráskód részlet futásánál ha hiba történik, akkor az except és end közötti programrészlet fut le. Ha a try és except közötti rész hiba nélkül lefutott, akkor az except és end közötti kód egyszer sem kerül futtatásra.
Nézzük ennek megfelelően az előbbi nullával való osztás forráskódját. Ha hiba történik, akkor a hibaüzenetünket a Label2-re írjuk ki. Mivel kezeljük a hibát a try-except-end által, így a Delphi saját hibakezelője már nem kap szerepet.
procedure TForm1.Button2Click(Sender: TObject);
var
  a, b, c: double;
begin
  try
    a:=10;
    b:=0;
    c:=a/b;
    Label1.Caption:=Format('%g', [c]);
  except
    Label2.Caption:='Hiba történt!';
  end;
end;

Amikor a try-except közé több sornyi forráskódot is írunk és hiba történik, akkor joggal merülhet fel a kérdés, hogy vajon hol történt a hiba és pontosan mi is az.

A harmadik nyomógombnál lévő forráskódnál továbbfejlesztettük az előzőt, hogy pontos információt is kapjunk a hiba jellegéről. Ehhez arra van szükség, hogy az except-end közé az alábbi kódot írjuk.
procedure TForm1.Button3Click(Sender: TObject);
var
  a, b, c: double;
begin
  try
    a:=10;
    b:=0;
    c:=a/b;
    Label1.Caption:=Format('%g', [c]);
  except
    on E: Exception do begin
      Label3.Caption:='Hiba történt: '+e.Message;
    end;
  end;
end;
Az on E: Exception do begin sor hatására létrejön egy lokális változó az E. Ennek típusa Exception lesz. A változó rögtön inicializálásra is kerül az aktuális hiba által, így az E változó rögtön használható is. Az Exception osztályról még később lesz szó, most elegendő annyit tudni, hogy van egy Message nevű sztring típusú property-je, mely az első nyomógombnál ismertetett hibaüzenet szövegét fogja tartalmazni. Ezt akár mi magunk is felhasználhatjuk, ahogy ez a harmadik gombnál látható is.


A negyedik gomb esetében további információt szerzünk a hibáról: programunkat felkészítjük két különböző hibalehetőség eltérő kezelésére. Az egyik hiba továbbra is a nullával való osztás lesz, míg a második hiba akkor keletkezik, ha megpróbáltatjuk kiszámítani a számítógéppel, hogy mennyi az ezer az ezrediken. Ha minden jól megy, akkor ez túl nagy szám lesz és így túlcsordulási hibát kapunk. Hogy mikor melyik hiba jöjjön létre, azt a negyedik gomb alatt található TCheckBox-al szabályozhatjuk.

Nézzük most a hibakezelést. Az exception-end közötti részen most a következő áll:
…
  except
    on e: EZeroDivide do begin
      Label4.Caption:='EZeroDivide hiba történt: '+e.Message;
    end;
    on e: EOverflow do begin
      Label4.Caption:='EOverflow hiba történt: '+e.Message;
    end;
  end;
…
Ha megfigyeljük az except-on-end megvalósítás nagyban hasonlít nem csak kinézetre, hanem működés szempontjából is a case-of-end programszerkezetre. Ha nullával való osztás történik, akkor az on e: EZeroDivide do begin ág fut le, ha túlcsordulás, akkor pedig az on e: EOverflow do begin ág kap szerepet.

Az előbbi nyomógombnál az Exception osztályt használtuk a nullával való osztás hibájához, most meg az EZeroDivide osztályt. Ezt azért tehettük, mert az EZeroDivide osztály az Exception osztályból származik.

Amint látható tehát a megtörtént hibát úgy kezelhetjük le, hogy az adott hibát kezelő osztály segítségével többfelé ágaztatjuk a programunkat.

Az ötödik nyomógomb esetében szintén két hibát idézhetünk elő. Az egyik továbbra is a nullával való osztás, míg a másik hiba egy nem létező állomány megnyitásakor keletkezik.

Ebben a példában azt szeretnénk bemutatni, hogy ahogyan a case-of-end programszerkezet esetén használhatunk egy else ágat is azokra az esetekre, melyeket nem soroltunk fel, így lehetőségünk van az except-on-end esetén is else ágat alkalmazni.

Így ha nem EZeroDivide hiba keletkezett, akkor az else ágon folytatódik tovább a program futása.
…
  except
    on e: EZeroDivide do begin
      Label5.Caption:='EZeroDivide hiba történt: '+e.Message;
    end;
    else begin
      Label5.Caption:='Egyéb hiba történt';
    end;
  end;


Cikksorozat



Könyv
Ez a cikk megtalálható ebben a könyvben: Delphi Software Offline 2000 évkönyv 523. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |