![]() |
Exceptions gehen zwischen den Threads verloren?
hallo zusammen.
Ich versuche mich z.Zt an einer Oberfläche für SQL-DBs. Solange es keine Fehler in der SQL-Source gibt läuft alles gut. Sobald dann ein Tippfehler oä auftaucht wird es unangenehm, weil die entsprechende Fehlermeldung teilweise verschluckt wird.
Delphi-Quellcode:
Mit
ADOQuery1.close;
ADOQuery1.SQL.Text:=QueryText.Text; try ADOQuery1.open; except on E: Eoleexception do begin { show all errors!} // ShowMessage(GetADOErrorString(ADOConnection1)); // E.Message:=GetADOErrorString(ADOConnection1); raise exception.create(GetADOErrorString(ADOConnection1)); end; end;
Delphi-Quellcode:
wird die Fehlermeldung manchmal unvollständig angezeigt,
ShowMessage
mit
Delphi-Quellcode:
und
E.Message
Delphi-Quellcode:
wird die Fehlermeldung in den meisten Fällen verschluckt.
raise Exception
U.U muß ich hinzufügen, daß Abfrage und Auslesen der Daten jeweils in einem eigenen Thread laufen. Wie mache ich es richtig, daß der Benutzer über Fehler benachrichtigt wird? Gruß K-H |
AW: Exceptions gehen zwischen den Threads verloren?
Was genau läuft denn jetzt in welchem Thread?
Wenn du aus einem Thread heraus etwas anzeigen willst, musst du Synchronize() (o.ä.) benutzen. Ansonsten hoffe ich mal, dass du nicht aus dem Thread heraus auf ADO-Komponenten auf dem Formular zugreifst. |
AW: Exceptions gehen zwischen den Threads verloren?
Fehler bei der Nutzung der ADO-Komponenten fange ich immer so in der Art ab:
Delphi-Quellcode:
Informationsverluste sind mir da bisher nicht aufgefallen.
try
Con.Connected := true; qry.SQL.Text := 'select * from Tabelle'; qry.Open; Except on e : EAdoError do begin slError := TStringList.Create; slError.Add(e.Message); if con.Errors.Count > 0 then begin for i := 0 to con.Errors.Count - 1 do begin slError.Add('Number: ' + IntToStr(con.Errors.Item[i].Number)); slError.Add('NativeError: ' + IntToStr(con.Errors.Item[i].NativeError)); slError.Add('Description: ' + con.Errors.Item[i].Description); slError.Add('Source: ' + con.Errors.Item[i].Source); slError.Add('HelpFile: ' + con.Errors.Item[i].HelpFile); slError.Add('SQLState: ' + con.Errors.Item[i].SQLState); end; MessageDlg(slError.Text,mtError, [mbOk],0); end else begin MessageDlg(e.Message + #13#13 + qry.SQL.Text, mtError, [mbOk], 0); end; slError.Free; end; on e : Exception do begin MessageDlg(e.Message + #13#13 + qry.SQL.Text, mtError, [mbOk], 0); end; (Die Aussagefähigkeit dieser Meldungen ist allerdings auch nicht immer unbedingt prickelnd ;-)) |
AW: Exceptions gehen zwischen den Threads verloren?
@nahpets
auf den ersten Blick das sieht meiner Procedure recht ähnlich:
Delphi-Quellcode:
ich schau es mir mal näher an.
function GetADOErrorstring(conn:TADOConnection):string; { nur die ADO-Errors!}
var iError : Integer; sError : string; begin if conn.Errors.Count>0 then begin sError:=format('ADO-Error(s): %d',[conn.Errors.Count])+CRLF+CRLF; for iError := 0 to conn.Errors.Count - 1 do begin {-- ADO Errors: } sError:=sError+Format('Error-No.: 0x%x',[conn.Errors[iError].Number])+CRLF; sError:=sError+Format('%s; (SQLState: %s)',[conn.Errors[iError].Description, conn.Errors[iError].SQLState])+CRLF; sError:=sError+Format('Source: %s', [conn.Errors[iError].Source])+CRLF; sError:=sError+Format('NativeError: %d', [conn.Errors[iError].NativeError])+CRLF+CRLF; end; result:=serror; end; end;{-- GetADOErrorstring -------------------------------------------} Zitat:
Zitat:
Zitat:
Gruß K-H |
AW: Exceptions gehen zwischen den Threads verloren?
Zitat:
![]() Zitat:
|
AW: Exceptions gehen zwischen den Threads verloren?
Ok das mit der Messagebox scheint ja Hand und Fuß zu haben, versuch macht kluch. Aber was ist mit den Exceptions? ich meine mich zu erinnern, das eine Exception die Möglichkeit ist, ohne auf irgendetwas Rücksicht nehmen zu müssen, den Benutzer zu informieren. Gut ist etwas platt formuliert, aber von der Tendenz her richtig?
Datensensitive controls? Ich gehöre zu den wenigen, die die meiden wie der Teufel das Weihwasser. Alleine wenn du mal die Ausgabe irgendwohin umleiten mußt, ist der Aufwand viel zu groß, das dann zusammen zu stricken. Gruß K-H |
AW: Exceptions gehen zwischen den Threads verloren?
Zitat:
![]() Zitat:
|
AW: Exceptions gehen zwischen den Threads verloren?
Synchronize und Co. kopieren die Exception und lösen sie im aufrufenden Thread neu aus.
TThread.Execute tut das nicht. Dort ist man selbst verplichtet in OnTerminate, DoTerminate oder nach Beendigung des Threads das Property FatalException zu prüfen. Hatte das mal bei Borland/Codegear reportet, aber sie hatten wohl keine Lust diese Funktionialität direkt einzubauen (abschaltbar), so daß es keiner vergessen kann. Kann sein, daß es "früher", in uralten Delphis, nur innerhalb OnTerminate/DoTerminate auslesbar/verwendbar war und danach die Exception sofort freigegeben wurde. In neueren Delphis wird die Exception via ![]() |
AW: Exceptions gehen zwischen den Threads verloren?
Hallo zusammen,
erst einmal vielen Dank für die Hilfe! Nachdem ich zunächst die "Messageboxlösung" ausprobiert habe:
Delphi-Quellcode:
kann ich davon nur abraten, da auch dort manchmal ein Sprung ins Nirwana erfolgt.
...
msg:=GetADOErrorString(ADOConnection1); Messagebox(0,pAnsichar(msg),'ADO-DB Error',MB_OK); Ich hab jetzt den Vorschlag von EMBa eingesetzt und es scheint zu funktionieren. Wobei so richtig verstanden hab ich es nicht:
Delphi-Quellcode:
Gruß
// Cancel the mouse capture ??
if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0); {--- wofür soll das gut sein?} // Now actually show the exception if FException is Exception then {----- warum diese Unterscheidung?} Application.ShowException(FException) else SysUtils.ShowException(FException, nil); K-H |
AW: Exceptions gehen zwischen den Threads verloren?
Zitat:
Delphi-Quellcode:
sorgt nur dafür, daß das nachfolgende Fenster auch auf Mausclicks reagieren kann. Es könnte ja sein, daß sich gerade ein anderes Fenster die Maus gekrallt hat. In dem Fall würde zwar die Exception-Meldung angezeigt, der Anwender könnte diese aber nicht mit der Maus wegclicken.
WM_CANCELMODE
Was die Abfrage danach betrifft: Die Zuweisung nach
Delphi-Quellcode:
erfolgt durch einen Hard-Cast von
FException
Delphi-Quellcode:
. Man kann also nicht sicher sein, daß wirklich eine
ExceptObject
Delphi-Quellcode:
-Instanz drin steckt. Genau dies wird durch die (auf den ersten Blick unsinnige) Abfrage abgefangen.
Exception
Bonus-Wissen: Man kann nicht nur Exceptions raisen, sondern jede Klasseninstanz!
Delphi-Quellcode:
Was auch immer man damit bezwecken will.
raise TButton.Create(nil);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz