Obsługa błędów w programach i zapobieganie ich występowaniu. Prezentację przygotowali: Łukasz Dryja Witold Święcki Dariusz Tomala
Istota błędów. Błędy podczas wykonania programu powodowane są wieloma różnymi przyczynami. Wśród nich można wymienić następujące: błędy projektowe, błędy kodowania, uszkodzenia sprzętu, niewłaściwe dane itp. Nie jest możliwe przewidzenie wszystkich możliwych błędów, można jednak zaplanować obsługę niektórych z nich.
Obowiązkiem programisty jest zapewnienie sposobu informowania o błędach, komunikowania się i (jeżeli to możliwe) poprawiania tych błędów. Można to zrobić przez dołączenie odpowiedniego kodu obsługi błędów w aplikacjach.
Rodzaje błędów Błąd kompilacji - to pomyłka programisty, która łamie zasady składni Visual Basic (błędne napisanie własności lub słowa kluczowego). Visual Basic zwraca uwagę na kilka typów składni w programach. Visual Basic nie pozwoli na uruchomienie programu, dopóki nie zostaną poprawione wszystkie błędy składni
Błąd podczas działania programu – to błąd, który powoduje nieoczekiwane zatrzymanie działania programu. Takie błędy powstają, gdy zewnętrzne zdarzenie lub nie wykryty błąd składni zmusza program do zatrzymania swojego działania, np. błąd w pisowni ładowanego pliku, lub brak dyskietki w stacji dyskietek.
Błąd logiczny - błąd człowieka - pomyłka programisty, która powoduje, że kod programu generuje złe wyniki. Większość wysiłków przy usuwaniu błędów koncentruje się na znajdywaniu błędów logicznych wprowadzonych przez programistę. Błędy te są często trudniejsze do zlokalizowania i poprawienia.
Jak unikać błędów. Istnieją dwie główne techniki, które pozwalają na uniknięcie błędów występujących w kodzie źródłowym programu: Strukturalna obsługa wyjątków Narzędzia do śledzenia przebiegu programu dostępne w oknie Debug
Strukturalna obsługa wyjątków. Strukturalna obsługa zapewnia obsługę wyjątków sprzętowych i programach. Oba typy wyjątków traktowane są w taki sam sposób, wobec czego kod źródłowy obsługujący wyjątki ma bardzo prostą i uniwersalną składnię.
Strukturalnej obsługi wyjątków zapewnia ochronę programu przed nietypowymi sytuacjami. Obsługa wyjątków nie spowalnia znacznie programu i nie obciąża systemu, ale nie należy zbyt przesadnie korzystać z obsługi wyjątków. Jeśli mamy pewność, że w określonej części programu nie ma możliwości wystąpienia błędów to nie powieliśmy stosować obsługi błędów.
Błędy i wyjątki. Po pierwsze, wyjątek jest pewną odmianą błędu, ale błąd i wyjątek to nie to samo. Wyjątek to nieprawidłowe zachowanie się aplikacji, które może być spowodowane przez wiele różnych czynników. Większość błędów występujących w Visual Basic można obsłużyć za pomocą instrukcji On Error. Ten sposób nie jest strukturalny, więc może powodować niepotrzebne skoki do różnych części kodu źródłowego procedury
Wyjątki obsługuje się w odpowiednich strukturach, co jest bardziej zorganizowane formą rozwiązywania problemów z aplikacją
Kod on error Sub NazwaProcedury On Error GoTo MiejsceObslugiBledow Rozkazy procedur .................................. Exit Sub MiejsceObslugiBledow: Rozkazy obslugi bledow ......................................... Exit Sub End Sub
Obiekt Err Err.Description zawiera wyjaśnienie sytuacji, która spowodowała błąd. Err.Number zwraca numer błędu, który można wykorzystać do sprawdzenia rodzaju błędu.
Wybrane kody i komunikaty. 3 Return without GoSub 5 Invalid procedure call 6 Overflow 7 Out of memory 9 Subscript out of range 10 This array is fixed or temporarily locked 11 Division by zero 13 Type mismatch
Instrukcja Resume. Resume – pozwala na powtórne wykonywanie operacji zawierającej błąd, a następnie przejście dalej, jeżeli problem nie zostanie naprawiony przez użytkownika. Resume Next – pomija tę instrukcję i przechodzi do następnego wiersza. Resume linia – rozpoczyna działanie od numeru linii programu, określonego przez argument linia.
Blok Try Za pomocą bloku Try ... End Try zabezpieczamy odpowiednią cześć programu. Chroniony zestaw instrukcji wpisujemy po słowie kluczowym Try, a kończymy słowami kluczowymi End Try.
Składnia bloku Try...End Try Przykład funkcji Try Catch Ex As Exception End Try Słowo kłuczowe Try rozpoczyna część kodu, a End Try stanowi zakończenie bloku. Linijka Catch oznacza tę część kodu, która obsługuje ewentualny wyjątek.
Sekcja Catch W każdym bloku Try...End Try występuje jedna lub więcej sekcji Catch. Każda sekcja Catch jest przeznaczona do przechwytywania wyjątków jednego typu. Za pomocą kilku sekcji Catch można przechwytywać wyjątki określonego typu i rozwiązywać z nimi problemy w określony sposób.
Przechwytywanie kilku wyjątków Try 3 Catch eNoFilie As FileNotFoundException 4 ‘ obsługa wyjątku związanego z nieznalezieniem pliku 5 Catch e10 As IOExcpetion 6 ‘ obsługa wyjątku wejścia/wyjścia 7 Catch Ex As Exception 8 ‘ obsługa pozostałych wyjątków 9 End Try
Powyższy blok Try...End Try jest przeznaczony do wychwytywania błędów, które mogą występować podczas przetwarzania plików. W bloku są trzy odzielne sekcje służące do przechwytywania różnych typów wyjątków (FileNotFoundException, IOExpception, i inne wątki). Gdyby w bloku wykorzystano tyko jedna sekcję Catch, to należałoby napisać procedurę określającą typ wyjątku.
Przykładowe wyjątki ArgumentException ArgumentNullException Powstaje, gdy do procedury jest przesłana nieprawidłowa wartość dana. ArgumentNullException Występuje, gdy zostanie przesłana wartość Null do funkcji, która jej nie akceptuje. ArgumentOutRangeException Występuje, gdy do funkcji zostanie przesłana dana o nieprawidłowym rozmiarze, np.: gdy do funkcji akceptującej wartość z zakresu od 1 do 12 prześlemy wartość –1. DivideByZeroException Występuje, gdy zachodzi próba dzielenia przez zmienną niezainicjowaną lub przechowująca wartość zero.
Zagnieżdżanie bloków Try...End Try Czasami istnieje potrzeba ochrony dwóch części kodu za pomocą bloków Try...End Try w taki sposób, by mieć możliwość niezależnej obsługi wyjątków występujących w poszczególnych częściach kodu. Jeśli mamy do czynienia z dwiema niezależnymi częściami, to po prostu każdą z nich zamykamy w bloku Try...Ed. Try. Jeśli obie części kodu są ze sobą w jakiś sposób powiązane, to trzeba skorzystać z zagnieżdżenia bloków Try...End Try.
Sub WriteToFile (ByVal FileName As Strin) Dim fsOut As System.IO.FileStream Dim strOut As System.IO.StreamWriter Try ‘ próba otwarcia pliku fsOut = _ New System.IO.FileStream(FileName, _ System.IO.FileMode.OpenOrCreate,_ System.IO.FileAccess.Write)
Try ‘zapis w pliku strOut = _ New System.IO.StreamWriter(fsOut) strOut.Write(Datetime.Today.ToString()) Catch eIO As Exception Console.WriteLine(‘’ ‘ nie można zapisać w pilku: {0}.”, FileName) End Try Catch eFile As Exception Console.WriteLine(‘’ nie można otworzyć pliku: {0}.”, Filename) End Sub
W tym przykładzie użyto dwóch bloków Try. End Try W tym przykładzie użyto dwóch bloków Try ... End Try. Jeden z nich (rozpoczynający się w linii 10.) jest w całości umieszczony w drugim bloku. Wewnętrzny blok nazywamy blokiem zagnieżdżonym w bloku zewnętrznym. Jeśli wystąpi wyjątek związany z zapisem do pliku 14., a użytkownik zobaczy na ekranie komunikat: „Nie można zapisać w pliku: SomeFile.Out.” Jeśli plik nie może zostać
c.d. otwarty, to wyjątek zostanie wyłapany przez instrukcję Catch z lini 18., a użytkownik zobaczy informację: „Nie można otworzyć pliku: SomeFile.Out”. Sposób działania zagnieżdżonych bloków Try ... End Try jest bardzo podobny do działania zagnieżdżonych instrukcji warunkowych If ... End If. Bloki możemy zagnieżdżać bez ograniczeń, podobnie jak
Instrukcje warunkowe. Czasem zagnieżdżenie kilku powoduje, że kod źródłowy przybiera bardziej zorganizowaną formę.
Sekcja Finally Gdy korzysta się z bloków Try, trzeba czasem zapewnić wykonanie określonego zadania, niezależnie od wystąpienia określonego błędu. Na przykład, podczas operacji zapisu danych w pliku należy bezwzględnie plik zamknąć po zapisie, niezależnie od tego, czy wystąpiły błędy, czy nie. Wykonanie określonego zadania, niezależnie od wystąpienia błędów podczas pracy programu, umożliwia sekcja Finally.
Tę sekcję wpisujemy pod sekcjami Catch Tę sekcję wpisujemy pod sekcjami Catch. W bloku Finally umieszczamy często instrukcje zamykające plik, przypisujące zmiennej wartość Nothing, i inne instrukcje „czyszczące” program. Przykładowy kod źródłowy z sekcją Finally przedstawiono na listingu.
Podsumowanie Wszystkie programy zawierają błędy. Czasem błędy powoduje użytkownik korzystający z programu w nieodpowiedni sposób. Aby uniknąć, należy przeanalizować działanie programu i uodpornić go na większość zdarzeń powodujących powstanie błędu. Najważniejszym zadaniem dla programisty jest ochrona przed utratą danych.
Literatura Internet: ”Visual Basic. Net” - autorzy: ”Visual Basic. Net” - autorzy: Duncan Mackenzie , Kent Sharkey Internet: http://vb4all.canpol.pl/