Frábrigðissýslari

**Frábrigðissýslari** er notaður til að bregast við frábrigðum (e. *exceptions*) frá eðlilegu flæði í forritum. Þessi frábrigði er erfitt, ef ekki ómögulegt, að sjá fyrir. Mögulegt frábrigði er t.d. þegar reynt er að tengjast gagnagrunni sem ekki er til, opna skemmda skrá eða tengjast tölvu sem slökkt er á.

## Stuðningur við frábrigði í forritunarmálum
Mörg forritunarmál hafa stuðning við frábrigðissýslara, t.d. C++, Delphi, Java, PHP, Python og öll .NET forritunarmálin. Fyrir utan smávægilegan blæbrigðamun nota þessi forritunarmál áþekkan rithátt.  Algengest er að notaðar séu „try“, „catch“ og „finally“ skipanir. Nánari lýsing hér að neðan.

## Algengar skipanir við frábrigði
### Try
Try blokkin heldur einfaldlega utan um þær aðgerðir sem fylgjast þarf með hvort veki upp frábrigði eða þar sem fylgjast þarf með að ruslasöfnun eigi sér stað eftir keyrslu blokkarinnar.

### Catch
Á eftir „try“ blokk getur fylgt engin eða margar „catch“ blokkir sem geta sérhæft sig í að afgreiða hver sína tegund af frábrigðum. Fyrst í „catch“ blokkinni er tiltekin tegund af frábrigði og tilvik sem hægt er að nota í blokkinni til að nálgast frekari upplýsingar um frábrigðið. Þegar villu er kastað í „try“ blokkinni er leitað eftir tilheyrandi frábrigðissýslara í „catch“ blokkum. Í „catch“ blokkinni er svo tekið á vandamálinu, ef t.d. frábrigðið er „FileNotFoundException“ gætum við skrifað skipanir í blokkina sem birta notandanum skilaboð um að skráin hafi ekki fundist og boðið honum að leita sjálfur.

Ekki er æskilegt að grípa allar villur, t.d. villur eins og „NullPointerException“ er best að láta flæða áfram til stýrikerfis sem stöðvar keyrslu og birtir villuboð.

### Finally
Þessi blokk er almennt notuð til að losa um auðlindir. T.d. loka skrá, loka tengingum við net og gagna grunna. Stundum er hámark sett á tengingar við gagnagrunna og er þess vegna nauðsynlegt að hafa ekki fleiri en nauðsyn krefur opnar í einu. Skipanir í þessari blokk er nánst undantekninga laust keyrðar áháð útkomunni í „try“ blokinni. Ef frábrigði kemur upp í „try“ blokk er leitað af tilheyrandi frábrigðissýslara ef hann finnst eru skipanir í honum keyrðar og svo skipanir í „finally“ blokinni, ef engin frábrigðissýslari finnst er farið beinnt í að keyra skipanir í „finally“ blokkinni.

Hægt er að nota „try“ og „finally“ blokkir saman án „catch“ blokka, og er þá „finally“ blokkin aðallega til að hreinsa upp auðlindir.
 
## Dæmi
Hér er dæmi um rithátt og skýringar á aðgerðum í forritunarmálinu Java. Hægt er að hafa enga eða margar „catch“ blokkir og meðhöndla þá hvert frábrigði fyrir sig, með mismunandi aðgerðum.

```
JAVA
try
{
   // Alla jafna keyrir kóði innan þessara slaufusviga frá byrjun til enda
   // og framkvæmir svo það sem er í "finally" blokkinni.
   // En stundum getur komið frábrigði annað hvort beinnt með "throw" skipun eða 
   // eða óbeint með kalli í fall sem kastar villu með "throw" skipun.
}
catch ( // Sértækasta frábrigði sem við viljum grípa )
{
   // Hér kemur aðgerð sem við viljum framkvæma ef við gripum tiltekiið frábrigði hér að ofan.
}
catch ( // Altækasta frábrigði sem við viljum grípa )
{
   // Hér kemur aðgerð sem við viljum framkvæma ef við gripum tiltekiið frábrigði hér að ofan.
}
finally
{
   // Hér koma aðgerðir sem eru alltaf framkvæmdar þegar við komum út úr "try" blokkinni
   // hvort sem við komum út úr henni :
   // 1. á eðlilegan hátt.
   // 2. vegna "break", "continue" eða "return" skipunar.
   // 3. vegna frábrigðis sem var gripið og afgreitt af viðkomandi "catch" blokk.
   // 4. vegna frábrigðis sem var ekki gripið eða afgreitt af neinni "catch" blokk.
   // Ef "try" blokkin kallar á System.exit(), er keyrslu hætt án þess að "finally"
   // blokkin sé keyrð. 
}
```


Hægt er að skrifa föll sem kasta villum sem valda frábrigðum. Þetta er t.d. hægt að nota þegar 
setja þarf gildi á eigindum í klösum. Dæmið er skrifað í C#. Hér er kastað villu ef reynt er að skrá mánuði sem ekki eru til.

```
C#
public void SetMonth(int month)
{
   if(month >= 1 && month <= 12) 
   {
      this.month = month;  
   }
   else
   {
      throw new ArgumentOutOfRangeException("Month");
   }
}
```

Hér er svo dæmi um notkun á fallinu að ofan, einnig skrifað í C#. Þar sem við reynum að setja númer mánaðar sem 13 mun fallið kasta villu og valda frábrigði sem „catch“ mun grípa og skirfa þá út á skjáinn eftirfarandi: „Ekki er hægt að setja númer mánaðar lægri en 1 og hærra en 12“.

```
C#
static void Main(string[] args)
{
   Class klasi = new Class();
   try
   {
      klasi.SetMonth(13);
   }
   catch (ArgumentOutOfRangeException)
   {
      Console.WriteLine("Ekki er hægt að setja númer mánaðar lægri en 1 og hærra en 12");
   }
}
```

## Hollráð varðandi frábrigði
*Ekki grípa frábrigði sem þú kannt ekki að afgreiða, þetta þýðir að annaðhvort getur þú lagað villuna sem olli frábrigðinu eða afturkallað aðgerðina sem olli því. Ef þú kannt að afgreiða afbrigðið þá skaltu grípa það, annars **ekki**.
*Lærðu að endurkasta frábrigðum.
*Ekki gleypa frábrigði.
*Notaðu „using“ eða „try/finally“ oft.

## Heimildir: