Jak poprawnie używać try, catchów

Jak poprawnie używać try, catchów
Kordoba
  • Rejestracja:około 5 lat
  • Ostatnio:dzień
  • Postów:151
0

Witam, jak poprawnie używać try catchów?
Zastanawiam się kiedy blok kodu otaczać try'em? Przecież tak naprawdę każda instrukcja może wyrzucić wyjątek? Choćby wyjście poza zakres tablicy. W takim wypadku można powiedzieć że cały program powinien być try'u. Może należy brać takie instrukcje które wyrzucają wyjątek nie z błędu programisty? Jak otwarcie FileStream (gdyż plik może nie istnieć), czy połączenie z bazą danych
(brak internetu). Prosiłbym o wytłumaczenie tego zagadnienia.

AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:8 dni
  • Postów:3561
1

Ja bym zmienił patrzenie, nie "kiedy używać try", a "kiedy łapać catch". Zmiana czysto słowna, ale ważna

Łapać tam, gdzie jest z tego jakiś sens, gdzie da się coś mądrego z tym zrobić.
Inaczej mówiąc, w wielu miejscach nawet jak złapiemy wyjątek, niewiele z tym problemem zrobimy. Np funkcji obliczającej na tablicy przykładowe wyjście poza. Funkcja i tam musi wykonać return. Ale w punkcie wywołania BYĆ MOŻE tak.
Albo otwarcie połączenia do bazy w programie GUI. Samo w sobie jest nieudane, ale łapiąc w dobrym miejscu możemy usera poprosić o poprawienie parametrów.


Bo C to najlepszy język, każdy uczeń ci to powie
mad_penguin
mad_penguin
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Rzeszów
1

Pojedyncze instrukcje owijasz w try catch tam, gdzie spodziewasz się konkretnego błędu, który chcesz i możesz obsłużyć w konkretny sposób, np. błąd połączenia z bazą danych -> retry za 5 sekund, int.Parse nie przeszedł -> wyświetl błąd walidacji.
Dodatkowo możesz owinąć cały program żeby obsłużyć te błędy których nie przewidziałeś i np. zalogować błąd, wysłać telemetrię i wyświetlić komunikat "nieznany błąd, spróbuj ponownie".

edytowany 1x, ostatnio: mad_penguin
Grzegorz Świdwa
Grzegorz Świdwa
  • Rejestracja:ponad 5 lat
  • Ostatnio:około 4 lata
  • Postów:385
0
Kopiuj
int main()
{
     string UserName;
     try
     {
          UserName.ToString(); // Powstanie wyjątek. Dostaniesz NullreferenceException. Zamiast program się wyłączyć przekaże ten wyjątek do Catch()
     }
     catch(Exception e)
     {
          Console.WriteLine("Nie wykonasz operacji na UserName bo jest równy NULL");
     }
}
Zobacz pozostały 1 komentarz
WeiXiao
@Afish: wiesz może kiedy Console.WriteLine() rzuci wyjątek?
AF
@WeiXiao: Zależy, o jakim wyjątku mówisz. Chociażby to: string s = new string('a', 1000*1000*1000); Console.WriteLine(s) spowoduje wyjątek na .NET Framework na x86 (być może trzeba zrobić jeszcze dłuższego stringa, zależy od ASLR i szczęścia). Zobacz, że https://referencesource.microsoft.com/#mscorlib/system/io/textwriter.cs,468 alokuje tablicę długości string + 2, więc możesz dostać OOM. Możesz też zrobić StackOverflowException bez problemu.
WeiXiao
@Afish: a taki zwykły Console.WriteLine("dupa"); kojarzysz kiedy by mógł rzucić?
AF
Jak nie liczymy SOE, zamknięcia strumienia przez refleksję, braku uprawnień do konsoli, to zakładam, że nie powinien rzucić.
Grzegorz Świdwa
Grzegorz Świdwa
To oczywiste, że można po prostu sprawdzić string.IsNullOrEmpty()
ZK
  • Rejestracja:prawie 7 lat
  • Ostatnio:5 miesięcy
  • Postów:273
1

Po pierwsze. Nie każda instrukcja musi wyrzucić wyjątek.
Po drugie. Przed błędami można się bronić w różny sposób.Można np. sprawdzić poprawność wprowadzanych danych.
Instrukcji try catch używa się w ostateczności dlatego że to jest dodatkowe niepotrzebne obciążenie dla procesora.

Napisałeś jeszcze że najlepiej byłoby cały program ująć w instrukcję try.
Nie chodzi tylko o to, żeby przechwycić każdy błąd ale żeby wiedzieć jaki to jest błąd i odpowiednio obsłużyć dany błąd.

Radziłbym przeczytać chociaż jedną dobrą książkę o C#

edytowany 1x, ostatnio: Zimny Krawiec
Grzegorz Świdwa
Grzegorz Świdwa
  • Rejestracja:ponad 5 lat
  • Ostatnio:około 4 lata
  • Postów:385
1

Nawiązując do poprzedniego posta źle zrozumiałem pytanie. Myślałem, że pytasz się w jaki sposób używać try catch, a nie w jakich przypadkach.
Najprościej mówiąc try catch używa się wtedy, kiedy nie możesz wykryć błędu. W przykładzie pierwszym niewskazane jest używanie try catch, ponieważ możemy obsłużyć błędnie wpisane dane:

Kopiuj
bool Connect(string str)
    {
        if(string.IsNullOrEmpty(str))
            return false;
        return true;
    }
Kopiuj
if(Connect(null))
        {
              // wykonało się
        }
        else
        {
             // błąd
        }

W następnej metodzie nie możemy obsłużyć błędu i mamy dwa wyjścia:

Kopiuj
void Connect(string str)
    {
        if(string.IsNullOrEmpty(str))
            throw new ArgumentNullException();
    }

Wyjście 1: obsługa błędu przed wywołaniem

Kopiuj
if (string.IsNullOrEmpty(str))
        { }// obsługa błędu
        else
            Connect(str)

Wyjście 2: try catch

Kopiuj
try
        {
            Connect(str);
        }
        catch(Exception e)
        {

        }

Według mnie prawda jest taka, że chyba wszystko da się zrobić bez użycia try catch. Wystarczy mieć wiedzę na temat używanych metod, kontrolować wprowadzane dane zanim się ich użyje. Jednak - szczególnie w komunikacji sieciowej - przeszkód w połączeniu może być masa i te błędy nie muszą leżeć po naszej stronie. Wtedy warto użyć try catch aby pozbyć się nawet takiego problemu jak zanik internetu **podczas **pobierania danych z bazy danych (bo przecież można było wcześniej sprawdzić czy jest).

Wybór czy użyć czy nie leży po strony programisty. Musi on sam ocenić czy bez tego jego aplikacja będzie niezawodna

edytowany 1x, ostatnio: Grzegorz Świdwa
jasmina tmp
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad rok
  • Postów:10
0

Nie wiem czy wszystko się da zrobić bez użycia try catch, widziałem Apki korzystające z bibliotek trzecich które czasem sypnął wyjątkiem nie wiedzieć z czego i po co - bo coś się tam zmieniło.
Wyjątki są OK, lepiej nastawić się gdzieś catchem blisko wyjątku na poziomie kodu bo gdzieś tam na górze jest jakiś globalny catch ale może być różnie z diagnostyką problemu.
Drugi aspekt to co zrobić z wyjątkiem i z użytkownikiem.
Poprawcie mnie jeśli się mylę, ale aplikacja desktopowa jak nie przechwyci wyjątku to się zatrzyma z brzydkim stack tracem, aplikacja webowa typu Asp.Net pewnie przechwyci wyjątek na poziomie strony, lub aplikacji i wyświetli 404 ErrorPage.
Co ma zrobić z tym użytkownik?
Jak się da - to wyświetlić mu co należy poprawić, jeśli nie, a nie jest to krytyczna funkcjonalność to LOG Exception i puścić program dalej z jakimś WARN, a jeśli jest to krytyczna funkcjonalność to LOG + komunikat że się nie da ERROR + jakiś email do supportu.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)