pełny odzysk numerów wyjątków

0

bez względu na to jaki błąd mój program wywołuje, chciałbym użytkownikowi podać domyślny tekst tego błędu i jego numer. jak to najskuteczniej zrobić ?
najpierw próbowałem tak (oczywiście w bloku try-except):

 on E:Exception do
    begin
    result:='#'+E.Message;
    FErrorCode:=...;
    end;

...okazało się że nie wszystkie klasy błędów (a w szczególności ogólna) mają właściwość ErrorCode. czy to znaczy że niektóre w ogóle nie mają przypisanego numeru ?
na grupie znalazłem coś takiego:
http://groups.google.com/group/borland.public.delphi.objectpascal/browse_frm/thread/d9a5d46404ac8c/2eb9dd209a3a195a?lnk=st&q=EFOpenerror&rnum=4#2eb9dd209a3a195a
więc spróbowałem:

 on E:Exception do
    begin
    result:='#'+E.Message;
    FErrorCode:=GetLastError;
    end;

w błędzie jednak był ktoś kto myślał że to działa. mi nie działa. GetLastError=0. Intuicja podpowiedziała mi żeby przed słówkiem except zapisać w lokalnej zmiennej GetLastError, jednak jak to nierzadko bywa, myliła się również.

jedyne rozwiązanie które widzę w tej chwili to stworzyć przypadki (on...do) dla wszystkich możliwych wyjątków, i przy tych które posiadają właściwość ErrorCode - skorzystać z niej, a dla innych zgłosić że błąd nie ma numeru i już. ale to oczywiście nonsens bo klas wyjątków jest ciut dużo. więc jak się to powinno zrobić ? może da się jakoś sprawdzić czy powstały wyjątek publikuje właściwość ErrorCode ? ale wydaje mi się że jeszcze inaczej. pomożecie ? :)

0
snw napisał(a)

może da się jakoś sprawdzić czy powstały wyjątek publikuje właściwość ErrorCode ? ale wydaje mi się że jeszcze inaczej. pomożecie ? :)

To przecież świetne zadanie dla RTTI :)

0

o mechaniźmie RTTI wiem tylko tyle że istnieje :D i że można z jego pomocą ponoć łatwo zapisywać opcje interfejsu...
ale
spróbowałem tak:

    if E.FieldAddress('ErrorCode')<>nil then
       FErrorCode:=(E).ErrorCode;

i nie wiem jak zrzutować teraz E żeby uzyskać dostęp do pola, jak już wiem że takowe istnieje.
[EDIT]
literówka

0

Na podstawie Delphi 6. Vademecum profesjonalisty. Tom I.

// E to obiekt wyjątku (obiekt typu Exception)
var
  PropInfo: PPropInfo;
  ErrCode: Integer;
begin
  ErrCode := 0;
  PropInfo := GetPropInfo(Exception.ClassInfo, 'ErrCode');
    // tutaj nazwa właściwości
  if PropInfo <> nil then // publikowane pole o nazwie 'ErrCode' istnieje w obiekcie
  begin
    if PropInfo^.PropType^.Kind = tkInteger then
      // czy ta właściwość jest typu Integer?
      ErrCode := GetOrdProp(E, PropInfo);
  end;

Jeśli w obiekcie istnieje publikowane pole typu Integer o nazwie ErrCode, to zmienna ErrCode zawiera jego wartość; jeśli takie pole nie istnieje, zmienna ma wartość 0. Kodu nie testowałem, więc mogą być problemy, ale na jego podstawie wiesz już, czego w razie problemów masz szukać :)

0

wciąż jednak nie rozumiem innej rzeczy. otóż na przykład otrzymuję błąd EFOpenError o treści (wiem że tego pliku nie ma)

Can't open file [...]

bez żadnych konsekwencji dla IOResult ani GetLastError (obydwa zwracają 0 - czy nie powinno być inaczej ?) mam dostęp tylko do EFOpenError.Message wyjątku.
nie rozumiem, dlaczenie nie EInOutError ('File not found', ErrorCode 2).
wtedy miałbym numer kodu (przynajmniej tak zakładam, EFOpenError nie publikuje właściwości) - a tak - piękna lipa na skraju łąki.
[EDIT]
dziękuję brodny za powyższy post, zaraz to sprawdzę. zawartość tego postu nadal aktualna :)

0

żeby sobie rozjaśnić sprawę, wstawiłem do kodu prostą linijkę:

RmDir('aaa');

i okazuje się, że ta sama linijka, w tych samych warunkach, owszem zawsze generuje EInOutError (patrz post wyżej gdy otrzymuję niespodziewanie błąd spoza tej klasy), ale funkcja GetLastError raz zwraca odpowiednią (#2) wartość ('File not found' - w sumie nie wiem czemu nie #3 i 'Path not found' ale już mniejsza z tym), a raz po prostu zero, czyli tak jakby się nic nie działo (Exception.Message zawsze zwraca komunikat o błędzie).

innymi słowy - ma miejsce wyjątek, jego kod JEST powszechnie znany, ale z nieznanych mi przyczyn nie mam do niego dostępu tudzież nie zostaje mi objawiony (ta sama konkluzja dotyczy postu wyżej, tylko przyczyna trochę inna).

any1 can help me ?

[EDIT]
tak to teraz wygląda:

 on E:Exception do
    begin
    result:='#'+E.Message;
    FValueStr:=result;
    FErrorCode:=GetLastError;

    PropInfo := GetPropInfo(E.ClassInfo, 'ErrorCode');
    if PropInfo <> NIL then // to się nigdy w tym przypadku nie wykonuje bo dla tej klasy zawsze NIL
       FErrorCode:=GetOrdProp(E, PropInfo);

    if FErrorCode=0 then //czyli numer błędu pozostaje nieznany...
       FErrorCode:=999;
    end;

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