- Öåíòðàëèçèðàíî
îáðàáîòâàíå íà ãðåøêè
Ìîæåì äà íàñî÷èì îáðàáîòêàòà íà
ãðåøêàòà êúì öåíòðàëíî, îáðàáîòâàíå íà ãðåøêèòå:
On
Error Goto label
Åòî è ñêåëåò íà êîä:
Sub
Example( )
On
Error Goto ErrHandler
'' àêî ñå ñëó÷àò ãðåøêè
ïðè èçïúëíåíèå: run-time error
'' Visual Basic äèðåêòíî
ñå îáðúùà êúì ErrHandler
Exit
Sub
ErrHandler:
'' êîä çà îáðàáîòêà íà
ãðåøêè
'' èëè ïîäàâàíåòî èì êúì
ñïèñúê - calls list.
End
Sub
Ñëåä êàòî ðåä On Error Goto label ñå èçïúëíè, êàçâàìå, ÷å
çàïî÷âàíåòî íà ìàíèïóëàòîð íà ãðåøêà (error handler) íà åòèêåò ErrHandler å àêòèâíî (active).
Èìà íÿêîëêî âúçìîæíîñòè çà
îáðàáîòâàíå íà ãðåøêàòà. Íàé-÷åñòèÿ å ìîæå áè äà ñå èçâåäå ñúîáùåíèå è äà ñå ïèòà
ïîòðåáèòåëÿ çà êîðèãèðàùà àêöèÿ.
Äðóã îáù ñïîñîá å ïîäàâàíåòî íà
èíôîðìàöèÿ çà ãðåøêàòà êúì âèêàùàòà ïðîöåäóðà ñ ïàðàìåòðè èëè ñ âúðíàòà
ñòîéíîñò îò ïðèêëþ÷âàùàòà ôóíêöèÿ (offending function). Íàïðèìåð, àêî ôóíêöèÿòà å ïðîåêòèðàíà äà
ïðåèìåíîâà ôàéë, ôóíêöèÿòà ìîæå äà âðúùà öÿëî ÷èñëî êàòî êîä çà èíäèêèðàíå íà ãðåøêàòà èëè çà ïîêàçâàíå íà óñïåõà íà
îïåðàöèÿòà . Áè òðÿáâàëî
êîäúò çà ãðåøêà (error code) äà å 0 çà óñïåøíà îïåðàöèÿ, -1 àêî ôàéëúò íå ñúùåñòâóâà, -2 àêî íîâîòî èìå íà ôàéëà å
íåâàëèäíî è ò.í.
Òðåòàòà âúçìîæíîñò å äà ïîäàäåì
ãðåøêàòà íà âèêàùàòà ïðîöåäóðà ÷ðåç ìåòîä Err.Raise èçâèêàí âúòðå â àêòèâíèÿ ìàíèïóëàòîð
íà ãðåøêà (error handler):
Err.Raise(Err.Number,
Err.Source, Err.Description, _
Err.HelpFile,
Err.HelpContext)
Òîçè ïðîöåñ ñå íàðè÷à
ðåãåíåðèðàíå íà ãðåøêà (regenerating èëè reraising).
Ìîæå äà ñå äåàêòèâèðà àêòèâíèÿ ìàíèïóëàòîð
íà ãðåøêà (error handler) òàêà:
On
Error Goto 0
Àêî íÿìà àêòèâåí ìàíèïóëàòîð íà
ãðåøêà (error handler), òîãàâà VB ðåàãèðà
òàêà è íèå ùå îïèøåì òàçè ðåàêöèÿ â ñëåäâàùàòà òî÷êà.
- Íÿìà ìàíèïóëàòîð íà ãðåøêà
(error-handler)
Àêî íÿìà error handler â ïðîöåäóðàòà offending
procedure, çàùîòî íÿìà èíñòðóêöèÿ OnError â ïðîöåäóðàòà èëè çàùîòî å
äåàêòèâèðàí ñ On Error Goto 0 èíñòðóêöèÿ , Visual Basic àâòîìàòè÷íî ïðàùà ãðåøêàòà êúì error handler íà âèêàùàòà (calling) ïðîöåäóðà. Àêî è âèêàùàòà
ïðîöåäóðà íÿìà error handler, ãðåøêàòà ïðîäúëæàâà ïî ñïèñúêà íà
âèêàíèÿòà, çà äà îòêðèå òàêúâ (error handler). Àêî íå ñå íàìåðè, Visual Basic îáðàáîòâà
ãðåøêàòà êàòî ïîêàçâà ñúîáùåíèå è ïðåêúñâà èçïúëíåíèåòî íà àïëèêàöèÿòà.
8.2.2 Ñòðóêòóðèðàíî îáðàáîòâàíå íà ãðåøêè - Structured Exception
Handling
Òî èçïîëçâà ñòðóêòóðàòà Try...Catch...Finally çà äà îáðàáîòè
ãðåøêèòå. Êàêòî ìîæåì äà ñå óâåðèì, VB .NET's ñòðóêòóðèðàíîòî
îáðàáîòâàíå íà
ãðåøêè å ìíîãî ïîâå÷å îáåêòíî-îðèåíòèðàíî, âêëþ÷âàùî îáåêòèòå íà êëàñà Exception class è íåãîâèòå ïðîèçõîæäàùè êëàñîâå.
- Try...Catch...Finally
Ñèíòàêñèñ íà Try...Catch...Finally êîíñòðóêöèÿòà:
Try
tryStatements
[Catch1
[exception [As type]] [When expression]
catchStatements1
[Exit
Try]
Catch2
[exception [As type]] [When expression]
catchStatements2
[Exit
Try]
. . .
Catchn
[exception [As type]] [When expression]
catchStatementsn]
[Exit
Try]
[Finally
finallyStatements]
End
Try
Èíñòðóêöèÿ tryStatements
(êîÿòî ñå
èçèñêâà) êîíñòèòóèðà áëîêà Try êúäåòî ñà èíñòðóêöèèòå ìîíèòîðèðàùè çà
ãðåøêè ïðè VB. Âúòðå â áëîê Try, êàçâàìå, ÷å îáðàáîòâàíåòî íà
ãðåøêè å àêòèâíî (active).
Áëîêîâåòå Catch ñúäúðæàò êîäà, êîéòî èçïúëíÿâà îòãîâîðà íà VB "õâàùàíåòî" íà îòäåëíèòå ãðåøêè âúòðå â áëîê Try. Òàêà, áëîêîâåòå Catch
ñå ñúñòîÿò îò
ìàíèïóëàòîðè íà ãðåøêè (error-handlers) çà
áëîê Try.
Ôðàçèòå exception
[As type] è [When expression] ñà ñâúðçàíè ñ ôèëòðèòå (filters) âúâ
VB .NET äîêóìåíòàöèÿòà.  ïúðâèÿ ñëó÷àé, exception
å èëè ïðîìåíëèâà
îò òèï Exception, êîéòî å áàçîâèÿ
êëàñ, êîéòî "õâàùà" âñè÷êè
èçêëþ÷åíèÿ, èëè ïðîìåíëèâà íà åäèí îò ïðîèçõîæäàùèòå êëàñîâå îò Exception. Ïðèìåðíî ïðîìåíëèâàòà
äåêëàðèðàíà êàòî:
Catch
e As Exception
ùå õâàíå âñÿêà ãðåøêà. Ïðîìåíëèâàòà äåêëàðèðàíà êàòî:
Catch
e As ArgumentNullException
ùå õâàíå âñÿêà ãðåøêà îò êëàñ ArgumentNullException. Íàêðàòêî, type
å èìåòî íà åäèí
îò êëàñîâåòå Exception.
Ôèëòúðúò When òèïè÷íî ñå èçïîëçâà ñ
ïîòðåáèòåëñêè-äåôèíèðàíè ãðåøêè. Êîäúò â ñëåäíèÿ Try áëîê âäèãà ãðåøêà, àêî
ïîòðåáèòåëÿò íå âúâåäå ÷èñëî. Áëîêúò Catch õâàùà òàçè ãðåøêà:
Try
Dim
sInput As String
sInput
= Inputbox("Enter a number.")
If
Not IsNumeric(sInput) Then
Err.Raise(1)
End
If
Catch
When Err.Number = 1
Msgbox("Error1")
End
Try
Çàáåëåæåòå, ÷å òàêúâ êîä:
Dim
x As Integer
Try
x
= 5
Catch
When x = 5
MsgBox(x)
End
Try
íå ðàáîòè (èíñòðóêöèÿ Catch íèêîãà íÿìà äà ñå èçïúëíè) çàùîòî íå å ãåíåðèðàíà ãðåøêà.
Èíñòðóêöèÿ Exit Try ñå èçïîëçâà çà ïðåêúñâàíå íà âñÿêà ïîðöèÿ êîä íà Try...Catch...Finally áëîê. Îïöèîíàëíèÿ áëîê êîä finallyStatements
ñå èçïúëíÿâà
íåçàâèñèìî äàëè ñå ïîÿâÿâà ãðåøêàòà (èëè
å õâàíàòà), íåçàâèñèìî
äàëè èíñòðóêöèÿ Exit Try å èçïúëíåíà. Òîçè ôèíàëåí êîä ìîæå äà ñå èçïîëçâà çà èç÷èñòâàíå â
ñúáèòèåòî íà ãðåøêàòà . (Ïðè íàïèñâàíåòî íà Exit Try â êðàÿ íà áëîê Try, áëîêúò finallyStatements íå ñå èçïúëíÿâà, àêî íå ñå ïîÿâè ãðåøêà.)
VB ìîæå äà ïîäàäå ãðåøêà êúì call ñòåêà, êîãàòî îáðàáîòâà ñòðóêóðèðàíî
ãðåøêè, êàêòî ïðè íåñòðóñòóðèðàíî. Òîâà ñå ñëó÷âà ïðè ñëåäíèòå ñèòóàöèè:
· Àêî ãðåøêàòà ñå ïîÿâè âúòðå â
áëîê Try, êîéòî íå å îáðàáîòåí îò ñúùåñòâóâàùèÿ Catch áëîê
· Àêî ãðåøêàòà ñå ïîÿâè èçâúí âñåêè áëîê Try (îáåçïå÷àâàéêè ðàçáèðà
ñå, ÷å íÿìà àêòèâíè On Error-ìàíèïóëàòîðè íà ñòèëíèòå ãðåøêè).
Ïðèìåð:
Dim
x, y As Integer `äâåòå ñà ÷åëî÷èñëåíè - integers
Try
x
= y ` äåëåíèå íà íóëà
Catch
ex As Exception
msgbox(ex.Message)
End
Try
Çàáåëåæêà
×àñòòà ex As Exception îò
èíñòðóêöèÿ Catch å îïöèîíàëíà. Òóê èìàìå äâå öåëî÷èñëåíè ïðîìåíëèâè (integers). Ïðè îïèòà çà
äåëåíèå x íà y ñå ïîëó÷àâà ãðåøêà îò äåëåíèå íà íóëà, çàùîòî y íå å
èíèöèàëèçèðàíî è å ïî ïîäðàçáèðàíå 0. Äåëåíèåòî íà íóëà âäèãà ãðåøêà, êîÿòî
õâàùàòå â ñëåäâàùèÿ ðåä. Ïðîìåíëèâàòà ex å îò òèï Exception, êîéòî äúðæè òîêó ùî ïîÿâèëàòà ñå ãðåøêà è
âèå ïðîñòî ïðèíòèðàòå ñâîéñòâî Message,
êàêòî ïðàâèòå ñ Err.Description âúâ VB6.
Ôàêòè÷åñêè, ìîæåòå äà èçïîëçâàòå Err.Description, è îáåêò Err . Îáåêò Err ùå
èçòåãëè âñÿêî èçêëþ÷åíèå, êîåòî ñå å ïîÿâèëî. Íåêà â äàäåí ïðèìåð, äà ñå âäèãà
ïðîäèêòóâàíà îò ëîãèêàòà ãðåøêà, êîÿòî ðåãèñòðèðà àêî íà íÿêîé áàëàíñà íà
ñìåòêàòà ìó å ìíîãî íèñúê, à äðóãà ãðåøêà àêî áàëàíñà ìó å îòðèöàòåëåí:
Try
If
bal < 0 Then
Throw
New Exception("Balance is negative!")
ElseIf
bal > 0 And bal <= 10000 Then
Throw
New Exception("Balance is low; charge interest")
End
If
Catch
MessageBox.Show("Error:
" & Err().Description)
Finally
MessageBox.Show("Executing
finally block.")
End
Try
 òîçè ñëó÷àé, áèçíåñ ëîãèêàòà âè äèêòóâà, àêî íà íÿêîé
áàëàíñà êëîíè êúì íóëà, äà âäèãàòå ãðåøêà,
èíôîðìèðàùà çà òîâà. Àêî áàëàíñà å îêîëî 10,000 íî ñå çàäúðæà íàä íóëàòà, âèå îñâåäîìÿâàòå ïîòðåáèòåëÿ äà çàïî÷íå äà
îëèõâÿâà. Â òîçè
ñëó÷àé, Err().Description óëàâÿ îáÿñíåíèåòî, êîåòî ñòå ïðåõâúðëèëè âúâ
âàøåòî Exception.
Ìîæå äà èìàòå ìíîãî îïåðàòîðè Catch, çà äà ïðèõâàùàòå ðàçëè÷íè ãðåøêè. Çà äà ìîæå îïåðàòîð Catch äà õâàùà êîíêðåòíà ãðåøêà, òðÿáâà äà ïðèáàâèòå êëàóçà When êúì òîçè Catch.
Ïðîáâàéòå êîäà:
Try
x
= y `
Catch
ex As Exception When Err().Number = 11
MsgBox("You
tried to divide by zero")
Catch
ex As Exception
MsgBox("Acts
as catch-all")
End
Try
 òîçè ïðèìåð ïðîâåðÿâàìå çà ãðåøêà Err().Number ðàâíà íà 11, êîÿòî å ãðåøêà ïðè äåëåíèå ñ íóëà. Àêî ñå ïîÿâè
äðóãà ãðåøêà, ùå ñå õâàíå îò Catch áåç êëàóçà When. Åôåêòúò íà Catch áåç When å êàòî "else".
Êîäúò íå ìèíàâà ïðåç âñè÷êè èçêëþ÷åíèÿ (exceptions); ñïèðà íà ïúðâàòà ãðåøêà,
êîÿòî íàìèðà.
Àêî èñêàòå äà âúðâè íÿêàêúâ êîä íàêðàÿ,
íåçàâèñèìî îò îòêðèòàòà ãðåøêà, (èëè àêî íå
å îòêðèòà òàêàâà),
âèå òðÿáâà äà ïðèáàâèòå îïåðàòîð Finally:
Try
x
= y ` cause division by zero
Catch
ex As Exception When Err().Number = 11
MsgBox("You
tried to divide by zero")
Catch
ex As Exception
MsgBox("Acts
as catch-all")
Finally
MsgBox("Running
finally code")
End
Try
 òîçè êîä ñåêöèÿ Finally ùå ñå èçïúëíè.
Äà èçëåçåì (exit) îò îïåðàòîð Try ïî-ðàíî. Êëþ÷îâà äóìà Exit Try êàêòî âå÷å êàçàõìå å ïðåäâèäåíà çà
ïðåêúñâàíå íà áëîê Try ïî-ðàíî, èãíîðèðàéêè Finally.
Ñèíòàêñèñúò å:
Try
x
= y ` äåëåíèå íà íóëà
Catch
ex As Exception When Err.Number = 11
msgbox("You
tried to divide by zero")
Exit
Try
Catch
ex As Exception
msgbox("Acts
as catch-all")
Finally
msgbox("Running
finally code")
End Try