try + catch wollen nicht so wie ich...
-
Moin!
Ich muss in einer bestehenden Funktion eine Fehlerbehandlung einbauen, da ein Funktionsaufruf (SCSIScanFindSCSIScannerWithDialog) eine Ausnahme erzeugen kann, nämlich, wenn der Scanner nicht angeschlossen/eingeschaltet ist bzw. während der Suche nach dem Scanner per Button abgebrochen wird.
Zu diesem Zweck habe ich testweise try-/catch-Blöcke wie folgt gebildet:
void CScanDlg::Init() { try { char sTmp[128]; // CDialog::OnInitDialog(); // fontLog.DeleteObject(); fontLog.CreatePointFont(80,"Courier New"); // if(SCSIScanFindSCSIScannerWithDialog(0,&Hostadapter,&Target,&Lun)!=0) { MessageBox("Scanner nicht gefunden oder abgebrochen!","Fehler"); cPleaseWait.ShowWindow(SW_HIDE); this->DestroyWindow(); return; } // int rtn = SCSIScanOpen(Hostadapter,Target,Lun,IOPort,SCSIScanIfSCSIPassThrough,&pSCSIScanHandle); if(rtn!=0) { MessageBox("SCSIScanOpen!=0"); this->DestroyWindow(); return; } // m_SliderLeft.SetLineSize(5); m_SliderLeft.SetPageSize(500); m_SliderLeft.SetRange(0,iMaxPixelX,true); m_SliderLeft.SetPos(0); // m_SliderTop.SetLineSize(5); m_SliderTop.SetPageSize(500); m_SliderTop.SetRange(0,iMaxPixelY,true); m_SliderTop.SetPos(0); // m_SliderWidth.SetLineSize(5); m_SliderWidth.SetPageSize(500); m_SliderWidth.SetRange(0,iMaxPixelX,true); m_SliderWidth.SetPos(iMaxPixelX); // m_SliderHeight.SetLineSize(5); m_SliderHeight.SetPageSize(500); m_SliderHeight.SetRange(0,iMaxPixelY,true); m_SliderHeight.SetPos(iMaxPixelY); // rcScanRect.X=rcScanRectOrgSize.X=0; rcScanRect.Y=rcScanRectOrgSize.Y=0; rcScanRect.Width=rcScanRectOrgSize.Width=iMaxPixelX/iScanRectZoom; rcScanRect.Height=rcScanRectOrgSize.Height=iMaxPixelY/iScanRectZoom; }catch (...) { MessageBox("Catched!"); cPleaseWait.ShowWindow(SW_HIDE); return; } }Die Auswirkungen sind nun folgendermaßen: das Programm stürzt zwar nicht mehr ab, es wird jedoch nicht der Code im catch-Block abgearbeitet. Ebenso wird der Code ab der Funktion SCSIScanFindSCSIScannerWithDialog (die ja die Ausnahme erzeugt) nicht ausgeführt. Im Klartext: Es wird einfach kein weiterer Code der Funktion ausgeführt! Weder wird irgendeine MessageBox angezeigt, noch wird der "Bitte warten"-Dialog (cPleaseWait) geschlossen.
Wieso?? Wie muss ich die Fehlerbehandlung richtig implementieren? Wo ist der Fehler?
Gruß Matze
-
Du solltest mal nachsehen welche Art von Exception geworfen wird und diese als Parameter für den catch block nehmen.
Ist es als Bsp. eine normale std::exception dann schreibst halttry {} catch(std::exception& e) {}Probiers einfach mal.
rya.
-
Ergänzung:
Wenn ich mit dem Debugger schrittweise durch das Programm gehe, geht er auch in den catch-Block rein. Der Debug-Zeiger steht dann auf der MessageBox. Diese wird jedoch tatsächlich, wie gesagt, nicht ausgeführt. Ebenso wie der restliche Teil des Blocks.
-
Wie kann ich denn herausfinden, welche Art von Exception geworfen wurde? Ich habe bislang noch nie mit try/catch zu tun gehabt...
-
Rausfinden kannst du das in der Doku zu den Funktionen die du verwendest.
Aber wenn er im Debugger in den catch-Handler reingeht und sonst nicht, ist das wunderlich. Naja (...) heisst ja eigentlich auch ALLE exceptions. Hast du mal nen kompletten Rebuild probiert?
rya.
-
Bist du sicher, dass du nicht versuchst, die Release-Variante zu debuggen? Dann gibt es schon mal komische Effekte. Aber die MessageBox sollte auf jeden Fall kommen.
Probiers mal mit der allg. Exception und gib die Fehlermeldung aus, z.B.:
catch(CException* pEx) { char expbuf[256]; pEx->GetErrorMessage((LPTSTR)expbuf, 255); pEx->Delete(); }
-
Rebuild habe ich versucht, ohne Verbesserung. Auch das direkte Ausführen der EXE ohne Debugger macht keinen Unterschied.
Ich habe eben allerdings einen sehr komischen Umstand entdeckt:
Wenn ich die Ausnahme verursache (Scanner ist aus), geht er in den catch-Block. Der Debug-Zeiger steht auf der MessageBox, die jedoch nicht ausgeführt wird.
Ich bin wieder in meinem Hauptdialog (der die ganze Zeit offen ist). Der "Bitte warten"-Dialog (sollte ja eigentlich zerstört werden) ist natürlich weiterhin da (als TopMost sehr nervig).
Versuche ich nun, die gleiche Funktion wieder auszuführen (so dass der Dialog ScanDlg geöffnet wird), passiert gar nichts.
Führe ich eine ganz andere Funktion aus (aktuelles Bild speichern, ohne Dialog), wird diese korrekt ausgeführt. Gleichzeitig erscheint aber plötzlich die zuvor vermisste MessageBox! Es wird also mit deutlicher Verzögerung (und einem kleinen Schubser meinerseits) doch der komplette catch-Block ausgeführt, nur eben nicht an einem Stück. Häähh?!
Danach stürzt das Programm ab.
EDIT: Und zwar stürzt es bei dem Versuch ab, den Dialog neu zu erstellen (cScanDlg.Create()), was sonst natürlich klappt, da der Dialog korrekt zerstört wird.
-
Tester2 schrieb:
Bist du sicher, dass du nicht versuchst, die Release-Variante zu debuggen? Dann gibt es schon mal komische Effekte. Aber die MessageBox sollte auf jeden Fall kommen.
Probiers mal mit der allg. Exception und gib die Fehlermeldung aus, z.B.:
catch(CException* pEx) { char expbuf[256]; pEx->GetErrorMessage((LPTSTR)expbuf, 255); pEx->Delete(); }Ich habe dies versucht, jetzt geht er allerdings gar nicht mehr in den catch-Block rein...
-
Ach ja, ich kompiliere natürlich als Debug, das kann's also auch nicht sein.