Try... except i obsługa błędów w MySQL DAC.

0

w systemie, który tworzę istnieją dwie aplikacje działające w trybie usługi i jedna klasyczna okienkowa.

Pojawił się ostatnio problem. Jedna z usług zatrzymywała się w trakcie pracy. Używam dość intensywnego systemu logowania pracy aplikacji usługowych do plików tekstowych. NIestety - tutaj aplikacja nie zgłosiła żadnego błędu i nie załapała się na część komunikatów logowanych do pliku.

Po żmudnym procesie debugowania okazało się, że popełniłem drobny błąd w zapytaniu SQL.

feralne zapytanie opakowałem klauzulą try...except, a w sekcji except uzyłem procedur związanych z logowaniem. Aplikacja rzeczywiście ładnie zalogowała nieprawidłowe działanie aplikacji i od razu wiedziałem które zapytanie zadziałało nieprawidłowo.

Wszystko fajnie - ale komunikat logowany do pliku to jakiś łańcuch znaków stworzony przeze mnie. System bazodanowy zgłasza jednak konkretny błąd, który od razu naprowadza na przyczynę.

PYTANIE: Jak przekierować/obsłużyć błędy zgłaszane z systemu bazodanowego przez komponenty Zeosa (akurat w tym przypadku współpracuje z PostgreSQL).

Chodzi o to - w zwykłej aplikacji w przypadku wystąpienia błędu podczas wykonywania zapytania SQL - na ekranie pojawia się okienko z komunikatem. Chciałbym ten komunikat umieścić w pliku logu. Jak ?

0
try
  //tu błąd
except
  on E: Exception do
    ShowMessage(E.Message);
end;
0

Dzięki o wielki Misku - działa. Dokładnie o to mi chodziło.

Widzę, że będę musiał jeszcze wagon chleba zjeść, żeby choć trochę zmądrzeć.

0

mam podobny problem, pętlą while przenoszę dane z pliku tekstowego do bazy, jedno z pół oznaczone jest jednoznaczenie co generuje mi błąd podczas wprowadzania danych chciałbym aby po wystąpieniu błędu pętla przeszła do kolejnego kroku. Kod z którym mam problem wygląda tak:

While Not Eof(TF) Do
//...
 try
  MySQL50Connection.ExecuteDirect(zapytanie);
 finally
  Continue;
 end;
//...
end;

Nie wiem czy to ma znaczenie ale aplikacja pisana jest w Lazarusie pod Windowsem. Błąd jaki występuje to:
Error: Control flow statements aren't allowed in a finally block

o ile błąd jest wskazany o tyle nie mam pomysłu jak to zrealizować. Warunkiem rozwiązania problemu jest również aby użytkownikowi nie wyświetlił się komunikat oraz aby policzyć ilość duplikatów?

0

finally wykona się zawsze.

zrób to według tego schematu:

while ...
begin
  try
    wykonanie zapytania;
    jakieś dalsze przetwarzanie, które ma się wykonać, jeśli nie było wyjątku;
  except
    obsługa błędu - jakieś logowanie czy coś
  end;
end;

proponuję, żebyś przemyślał działanie wyjątków, bo widzę u Ciebie braki w dość podstawowej wiedzy jeśli chodzi o ten temat.

BTW - odświeżyłeś wątek sprzed CZTERECH lat. na przyszłość twórz nowy.

0

Wystarczyło przetłumaczyć treść błędu i zrozumiałbyś dlaczego się pojawia;

"Control flow statements aren't allowed in a finally block"
Błąd ten oznacza, że skok z bloku try .. finally jest niedopuszczalny; Trochę lepiej informuje o tym Delphi 7, bo podaje wszystkie niedozwolone instrukcje w takiej konstrukcji:

"Cannot BREAK, CONTINUE or EXIT out of a FINALLY clause"

Do łapania wyjątków służy blok:

try
  //kod mogący wywołać wyjątek
except
  //przechwytywanie i obsługa wyjątków
end;

Proponuję przestudiować artykuł na temat obsługi wyjątków.

0

proszę Państwa jestem zachwycony tak błyskawiczną odpowiedzią jednak problem nie został rozwiązany

  • instrukcja catch generuje mi błąd w kompilatorze,
  • except zapętla mi wyświetlanie komunikatu testowego
  • próbowałem coś takiego:
while
  try
    MySQL50Connection.ExecuteDirect(zapytanie);
  finally
    duplikat:=True;
  end;

 if duplikat=True then
 begin
   duplikat:=False;
   Continue;
 end;

dla finally wyskakiwał mój komunikat z błędem po wciśnięciu ok wyskakiwał komunikat programu (jak gdyby nie było try)
dla except zapętlał się mój komunikat, nie wiem w tym miejscu czy mam tyle duplikatów ale jak wcześniej zaznaczyłem program ma pominąć rekordy z duplikatami i kontynuować wprowadzanie danych bez wiedzy użytkownika?

jakieś inne rozwiązania?

0

Podałem Ci prawidłowe rozwiązanie. Najwyraźniej nie rozumiesz co robisz. Kod powyżej to chyba literówka ;-) Finally wykonuje się ZAWSZE! duplikat zawsze będzie mieć wartość true! A w try możesz mieć więcej, niż jedną instrukcję, więc używanie dodatkowych zmiennych jest równie potrzebne, co porównywanie boolean duplikat do true.
Komunikat z treścią wyjątku pokazuje się tylko dlatego, że uruchamiasz program pod debuggerem i Delphi przejmuje wszystkie lecące wyjątki, niezależnie od tego czy złapane, czy nie. Uruchom program bez debuggera, albo poza Delphi, albo wyłącz w konfiguracji Delphi przechwytywanie Twojego wyjątku. Uprzedzając pytanie jak to zrobić -> google. Samodzielne szukanie rozwiązania nie boli.

0

Szacun dla Ciebie kolego. Tak długo nad tym siedziałem że zacząłem kombinować. Rozwiązanie:

try
  MySQL50Connection.ExecuteDirect(zapytanie);
except
  duplikat:=True;
end;

if duplikat=True then
begin
  duplikat:=False;
  Continue;
end;

jest jak najbardziej słuszne. Dobrze jak przypuszczałem podczas instrukcji except program się zapętlał.

Rozwiązanie problemu:
Dane jakie importowałem do jednoznacznej kolumny tabeli to liczba. Jej wartość była w każdym przypadku większa od maksymalnej wielkości INT w bazie MySQL dlatego też komórka przyjmowała największą wartość z możliwych i blokowała możliwość wprowadzania kolejnych danych. Po ustawieniu atrybutu UNSIGNED w bazie program z powyższym rozwiązaniem działa.

p.s. Finally działa zawsze :)

0

zrób to porządniej i przepisz kod tak, żeby pozbyć się tej zmiennej

1 użytkowników online, w tym zalogowanych: 0, gości: 1