Poikkeusten käsittely Delphi-poikkeusten käsittelyssä

Tässä on mielenkiintoinen tosiasia: Ei koodi on virheetön - itse asiassa jokin koodi on täynnä "virheitä" tarkoituksella.

Mikä virhe sovelluksessa? Virhe on väärin koodattu ratkaisu ongelmaan. Sellaisia ​​ovat logiikkavirheet joka voi johtaa väärään toimintotulokseen, missä kaikki näyttää hienosti kootulta, mutta sovelluksen tulos on täysin käyttökelvoton. Loogisilla virheillä, hakemus saattaa lopettaa toimintansa.

Poikkeukset voivat sisältää virheitä koodissa, jossa yrität jakaa numeroita nolla tai yrität käyttää vapautettuja muistilohkoja tai yrität antaa väärät parametrit toiminnolle. Sovelluksen poikkeus ei kuitenkaan aina ole virhe.

Poikkeukset ja poikkeusluokka

Poikkeuksia ovat erityisolosuhteet, jotka vaativat erityistä käsittelyä. Kun tapahtuu virhetyyppinen tila, ohjelma nostaa poikkeuksen.

Sinä (sovelluksen kirjoittajana) käsittelet poikkeuksia tehdäksesi sovelluksestasi alttiimpia virheille ja vastataksesi poikkeuksellisiin olosuhteisiin.

Useimmissa tapauksissa löydät itsesi sovelluksen kirjoittajaksi ja myös kirjaston kirjoittajaksi. Joten sinun pitäisi tietää, kuinka nostaa poikkeuksia (kirjastostasi) ja kuinka käsitellä niitä (sovelluksestasi).

instagram viewer

Artikkeli aiheesta käsittelyvirheitä ja poikkeuksia tarjoaa joitain perusohjeita virheiden estämiseksi kokeile / paitsi / lopettaa ja yritä / lopulta / lopettaa suojattuja lohkoja poikkeuksellisiin olosuhteisiin reagoimiseksi tai käsittelemiseksi.

Yksinkertainen kokeilu / paitsi suojalohkot näyttää seuraavalta:


yrittää
ThisFunctionMightRaiseAnException ();
paitsi// käsittele kaikkia tässäFunctionMightRaiseAnException () -kohdassa () esitettyjä poikkeuksia
pää;

ThisFunctionMightRaiseAnException-sovelluksella voi olla toteutuksessaan koodirivi kuten


nostaa Poikkeus. Luo ('erityisedellytys!');

Poikkeus on erikoisluokka (yksi harvoista, joissa nimen edessä ei ole T: tä), joka on määritelty sysutils.pas-yksikössä. SysUtils-yksikkö määrittelee useita erityiskäyttöä koskevia jälkeläisiä (ja luo siten poikkeusluokkien hierarkia) kuten ERangeError, EDivByZero, EIntOverflow jne.

Useimmissa tapauksissa poikkeukset, joita käsittelisit suojatussa yrittämis- / paitsi -lohkossa, eivät ole poikkeuksia (perusluokka), mutta jostakin erityisestä poikkeuslaskelmasta, joka on määritelty joko VCL: ssä tai kirjastossa, jossa olet käyttäen.

Poikkeusten käsitteleminen kokeilun / poissulkemisen avulla

Pysyäksesi ja käsittelemällä poikkeustyyppiä sinun tulee konstruoida "on type_of_exception do" -käsittelijä. "Poikkeuksellisesti" näyttää melko samankaltaiselta kuin klassinen tapauslausunto:


yrittää
ThisFunctionMightRaiseAnException;
excepton EZeroDivide dobegin// jotain jakamalla nollapää;
päällä EIntOverflow dobegin// jotain, kun liian suuri kokonaislukulaskelmapää;
elsebegin// jotain, kun muita poikkeustyyppejä nostetaan esiinpää;
pää;

Huomaa, että toinen osa tarttuisi kaikkiin (muihin) poikkeuksiin, myös niihin, joista et tiedä mitään. Yleensä koodisi tulisi käsitellä vain sellaisia ​​poikkeuksia, jotka todella tiedät käsitellä ja jotka odottavat sinulta heitettävän.

Älä myöskään koskaan "syö" poikkeusta:


yrittää
ThisFunctionMightRaiseAnException;
paitsi
pää;

Poikkeuksen syöminen tarkoittaa, että et tiedä kuinka käsitellä poikkeusta tai et halua käyttäjien näkevän poikkeusta tai jotain sen välissä.

Kun käsittelet poikkeusta ja tarvitset siitä enemmän tietoja (se on loppujen lopuksi luokan esiintymää), pikemminkin vain poikkeuksen tyyppi, jonka voit tehdä:


yrittää
ThisFunctionMightRaiseAnException;
excepton E: Poikkeus dobegin
ShowMessage (E.Message);
pää;
pää;

"E" kohdassa "E: Poikkeus" on väliaikainen poikkeusmuuttuja, joka on määritetty sarakkeen merkin jälkeen (yllä olevassa esimerkissä peruspoikkeusluokka). E: n avulla voit lukea (tai kirjoittaa) arvoja poikkeusobjektille, kuten saada tai asettaa Viesti-ominaisuuden.

Kuka vapauttaa poikkeuksen?

Oletko huomannut, kuinka poikkeukset ovat oikeastaan ​​tapauksia luokasta, joka alenee poikkeuksesta? Nosta avainsana heittää poikkeusluokan ilmentymän. Mitä luot (poikkeusesimerkki on objekti), sinä myös täytyy vapauttaa. Jos luot (kirjaston kirjoittajana) ilmentymän, vapauttaako sovelluksen käyttäjä sen?

Tässä on Delfoi magia: Poikkeuksen käsitteleminen tuhoaa automaattisesti poikkeusobjektin. Tämä tarkoittaa, että kun kirjoitat koodin "paitsi / loppu" -lohkoon, se vapauttaa poikkeusmuistin.

Joten mitä tapahtuu, jos ThisFunctionMightRaiseAnException todella aiheuttaa poikkeuksen etkä käsittele sitä (tämä ei ole sama kuin "syö" sitä)?

Entä kun lukua / 0 ei käsitellä?

Kun koodiin heitetään käsittelemätön poikkeus, Delphi käsittelee jälleen taikuutta maagisesti näyttämällä virhevalintaikkunan käyttäjälle. Useimmiten tämä valintaikkuna ei tarjoa tarpeeksi tietoa käyttäjälle (ja lopulta sinulle) ymmärtääksesi poikkeuksen syyn.

Tätä ohjaa Delphin ylimmän tason viestisilmukka missä kaikki poikkeuksia käsittelee globaali sovellusobjekti ja sen HandleException-menetelmä.

Voit kirjoittaa TApplicationEvents-koodin käsitelläksesi poikkeuksia globaalisti ja näyttääksesi oman käyttäjäystävällisemmän valintaikkunan. OnException-tapahtumakäsittelijä.

Huomaa, että globaali sovellusobjekti määritetään Lomakkeet-yksikössä. TApplicationEvents on komponentti, jota voit käyttää sieppaamaan globaalin sovellusobjektin tapahtumat.