Her er en interessant kendsgerning: Nej kode er fejlfri - faktisk er nogle koder fulde af "fejl" med vilje.
Hvad er en fejl i et program? En fejl er en forkert kodet løsning på et problem. Sådanne er logiske fejl Det kan føre til forkerte funktionsresultater, hvor alt virker pænt sammensat, men resultatet af applikationen er fuldstændigt ubrugelig. Med logiske fejl, en Ansøgning måske eller måske ikke holder op med at arbejde.
Undtagelser kan omfatte fejl i din kode, hvor du prøver at opdele tal med nul, eller du prøver at bruge frigjorte hukommelsesblokke eller prøve at give forkerte parametre til en funktion. En undtagelse i en applikation er dog ikke altid en fejl.
Undtagelser og undtagelsesklassen
Undtagelser er særlige forhold, der kræver særlig håndtering. Når der opstår en fejltypetilstand, skaber programmet en undtagelse.
Du (som applikationsskribent) vil håndtere undtagelser for at gøre din ansøgning mere udsat for fejl og reagere på den ekstraordinære tilstand.
I de fleste tilfælde finder du dig selv at være applikationsskribenten og også biblioteksforfatteren. Så du bliver nødt til at vide, hvordan man hæver undtagelser (fra dit bibliotek), og hvordan man håndterer dem (fra din ansøgning).
Artiklen om håndteringsfejl og undtagelser indeholder nogle grundlæggende retningslinjer for, hvordan man beskytter mod fejl ved hjælp af try / undtagen / slut og prøve / endelig / slut beskyttede blokke til at reagere på eller håndtere ekstraordinære forhold.
En simpel prøve / undtagen beskyttelsesblokke ser ud:
prøve
ThisFunctionMightRaiseAnException ();
undtagen// håndtere eventuelle undtagelser, der er rejst i ThisFunctionMightRaiseAnException () her
ende;
ThisFunctionMightRaiseAnException har muligvis i sin implementering en kodelinje som
hæve Undtagelse. Opret ('speciel betingelse!');
Undtagelsen er en speciel klasse (en af få uden T foran navnet) defineret i enheden sysutils.pas. SysUtils-enheden definerer adskillige efterkommere med særlige formål, som er undtagelsesvis (og skaber således et hierarki af undtagelsesklasser) som ERangeError, EDivByZero, EIntOverflow osv.
I de fleste tilfælde er de undtagelser, du ville håndtere i den beskyttede prøve / undtagen blok, ikke undtagelsen (base) klasse, men af en eller anden speciel undtagelsesklasse defineret i VCL eller i det bibliotek, du er ved brug af.
Håndtering af undtagelser ved hjælp af Try / Except
For at fange og håndtere en undtagelsestype konstruerer du en undtagelseshåndterer "on type_of_exception do". "Undtagelsesvis gør" ligner stort set den klassiske sagopgørelse:
prøve
ThisFunctionMightRaiseAnException;
excepton EZeroDivide dobegin// noget, når vi deler med nulende;
på EIntOverflow dobegin// noget, når der er for stor heltalberegningende;
elsebegin// noget, når andre undtagelsestyper hævesende;
ende;
Bemærk, at den anden del griber alle (andre) undtagelser, inklusive dem, du intet ved om. Generelt skal din kode kun håndtere undtagelser, som du faktisk ved, hvordan du skal håndtere og forventer at blive kastet.
Du skal heller aldrig "spise" en undtagelse:
prøve
ThisFunctionMightRaiseAnException;
undtagen
ende;
At spise undtagelsen betyder, at du ikke ved, hvordan man håndterer undtagelsen, eller at du ikke vil have brugere til at se undtagelsen eller noget derimellem.
Når du håndterer undtagelsen, og du har brug for flere data fra den (det er trods alt et eksempel på en klasse), snarere kun den type undtagelse, du kan gøre:
prøve
ThisFunctionMightRaiseAnException;
excepton E: Undtagelse dobegin
ShowMessage (E.Message);
ende;
ende;
"E" i "E: Undtagelse" er en midlertidig undtagelsesvariabel af den type, der er angivet efter kolonnetegnet (i ovenstående eksempel basen undtagelsesklasse). Ved hjælp af E kan du læse (eller skrive) værdier til undtagelsesobjektet, f.eks. Hente eller indstille egenskaben Meddelelse.
Hvem frigør undtagelsen?
Har du bemærket, hvordan undtagelser faktisk er tilfælde af en klasse, der falder fra undtagelsen? Forøgelsessøgeordet kaster en undtagelsesklasseinstans. Hvad du opretter (undtagelsesinstansen er et objekt), du også har brug for at frigøre. Hvis du (som biblioteksforfatter) opretter en instans, vil applikationsbrugeren frigøre den?
Her er Delphi magi: Håndtering af en undtagelse ødelægger automatisk undtagelsesobjektet. Dette betyder, at når du skriver koden i "undtagen / slut" -blokken, frigiver den undtagelseshukommelsen.
Så hvad sker der, hvis ThisFunctionMightRaiseAnException faktisk rejser en undtagelse, og du ikke håndterer det (dette er ikke det samme som at "spise" det)?
Hvad med når nummer / 0 ikke håndteres?
Når en uhåndteret undtagelse kastes i din kode, håndterer Delphi igen magisk din undtagelse ved at vise fejldialogen til brugeren. I de fleste tilfælde giver denne dialog ikke tilstrækkelige data til, at brugeren (og til sidst dig) kan forstå årsagen til undtagelsen.
Dette styres af Delphis meddelelsessløjfe på højeste niveau, hvor alle undtagelser behandles af det globale applikationsobjekt og dets HandleException-metode.
Hvis du vil håndtere undtagelser globalt og vise din egen mere brugervenlige dialog, kan du skrive kode til TApplicationEvents. OnException-begivenhedshåndterer.
Bemærk, at det globale applikationsobjekt er defineret i formularenheden. TApplicationEvents er en komponent, du kan bruge til at opfange begivenhederne i det globale applikationsobjekt.