diff --git a/source/copytable.pas b/source/copytable.pas index 2fe61a88..667f4a4b 100644 --- a/source/copytable.pas +++ b/source/copytable.pas @@ -302,7 +302,7 @@ begin FreeAndNil(Fixes); Mainform.actRefresh.Execute; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOk], 0); ModalResult := mrNone; end; diff --git a/source/createdatabase.pas b/source/createdatabase.pas index 9cb37ff1..4951b6db 100644 --- a/source/createdatabase.pas +++ b/source/createdatabase.pas @@ -214,7 +214,7 @@ begin // Close form ModalResult := mrOK; except - On E:Exception do + on E:EDatabaseError do MessageDlg( 'Creating database "'+editDBName.Text+'" failed:'+CRLF+CRLF+E.Message, mtError, [mbOK], 0 ); // Keep form open end else try @@ -284,7 +284,7 @@ begin // Close form ModalResult := mrOK; except - On E:Exception do + on E:EDatabaseError do MessageDlg( 'Altering database "'+editDBName.Text+'" failed:'+CRLF+CRLF+E.Message, mtError, [mbOK], 0 ); // Keep form open end; diff --git a/source/editvar.pas b/source/editvar.pas index 889766f3..317a88ff 100644 --- a/source/editvar.pas +++ b/source/editvar.pas @@ -3,7 +3,8 @@ unit editvar; interface uses - Windows, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; + Windows, SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, + mysql_connection; type TfrmEditVariable = class(TForm) @@ -71,7 +72,7 @@ begin try Mainform.Connection.Query(sql); except - on E:Exception do begin + on E:EDatabaseError do begin ModalResult := mrNone; MessageDlg(E.Message, mtError, [mbOK], 0); end; diff --git a/source/event_editor.pas b/source/event_editor.pas index c710b3ed..643d702d 100644 --- a/source/event_editor.pas +++ b/source/event_editor.pas @@ -231,7 +231,7 @@ begin CreateCodeValid := False; UpdateSQLcode; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOk], 0); Result := mrAbort; end; diff --git a/source/loaddata.pas b/source/loaddata.pas index 21da695a..e46f7368 100644 --- a/source/loaddata.pas +++ b/source/loaddata.pas @@ -269,7 +269,7 @@ begin try Mainform.Connection.Query(query); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOk], 0); ModalResult := mrNone; end; diff --git a/source/main.pas b/source/main.pas index 19ffbb16..83564d60 100644 --- a/source/main.pas +++ b/source/main.pas @@ -997,7 +997,7 @@ begin Connection.Query('UNLOCK TABLES'); end; except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; end; @@ -2237,7 +2237,7 @@ begin InvalidateVT(DBtree, VTREE_NOTLOADED_PURGECACHE, False); ActiveDatabase := ''; except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; Exit; @@ -2276,7 +2276,7 @@ begin // Refresh ListTables + dbtree so the dropped tables are gone: Connection.ClearDbObjects(ActiveDatabase); except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; ObjectList.Free; @@ -2329,7 +2329,7 @@ begin try ConnectionAttempt.Active := True; except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; @@ -2450,7 +2450,7 @@ begin Connection.Query( sql_pattern + mask(t[i]) ); actRefresh.Execute; except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; t.Free; @@ -3245,7 +3245,7 @@ begin Row.Cells[i].IsNull := Data.IsNull(i); end; Row.HasFullData := True; - except On E:Exception do + except On E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; end; @@ -3466,7 +3466,7 @@ begin Data := Connection.GetResults(Select); except // Wrong WHERE clause in most cases - On E:Exception do + On E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; @@ -3913,7 +3913,7 @@ begin Connection.Query('KILL '+ProcessIDs[i]); end; except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; InvalidateVT(ListProcesses, VTREE_NOTLOADED, True); @@ -3981,7 +3981,7 @@ begin else ResultLabel.Caption := FormatNumber(Connection.RowsAffected) +' row(s) affected by last query.'; except - on E:Exception do begin + on E:EDatabaseError do begin if actQueryStopOnErrors.Checked or (i = SQL.Count - 1) then begin Screen.Cursor := crDefault; MessageDlg( E.Message, mtError, [mbOK], 0 ); @@ -4353,7 +4353,7 @@ begin // so we do it manually here DBTree.InvalidateChildren(FindDBNode(ActiveDatabase), True); except - on E:Exception do + on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; end; @@ -6202,7 +6202,7 @@ begin if VT.Tag = VTREE_NOTLOADED_PURGECACHE then try AllDatabases := Connection.AllDatabases; except - on E:Exception do begin + on E:EDatabaseError do begin AllDatabases.Clear; MessageDlg(E.Message+CRLF+CRLF+'You have no privilege to execute SHOW DATABASES. Please specify one or more databases in your session settings, if you want to see any.', mtError, [mbOK], 0); end; @@ -6280,7 +6280,7 @@ begin // Selecting a database can cause an SQL error if the db was deleted from outside. Select previous node in that case. try Connection.Database := newDb; - except on E:Exception do begin + except on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); SelectNode(DBtree, PreviousFocusedNode); Exit; @@ -6298,7 +6298,7 @@ begin newDb := AllDatabases[Node.Parent.Index]; try Connection.Database := newDb; - except on E:Exception do begin + except on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); SelectNode(DBtree, PreviousFocusedNode); Exit; @@ -6377,7 +6377,7 @@ begin end; lntView: ParseViewStructure(SelectedTable.Name, SelectedTableColumns); end; - except on E:Exception do + except on E:EDatabaseError do MessageDlg(E.Message, mtError, [mbOK], 0); end; end; @@ -6908,7 +6908,7 @@ begin end; Result := True; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Result := False; end; @@ -7138,7 +7138,7 @@ begin GridFinalizeEditing(Sender); InvalidateVT(DataGrid, VTREE_NOTLOADED_PURGECACHE, False); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Result := False; end; @@ -7179,7 +7179,7 @@ begin Connection.Query(sql); Result := True; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Result := False; end; @@ -7680,7 +7680,7 @@ begin if Connection.InformationSchemaObjects.IndexOf('SCHEMATA') > -1 then AllDatabasesDetails := Connection.GetResults('SELECT * FROM '+mask(DBNAME_INFORMATION_SCHEMA)+'.'+mask('SCHEMATA')); except - on E:Exception do + on E:EDatabaseError do LogSQL(E.Message, lcError); end; if vt.Tag = VTREE_NOTLOADED_PURGECACHE then begin @@ -7702,7 +7702,7 @@ begin if Assigned(ListDatabases.FocusedNode) then try ActiveDatabase := ListDatabases.Text[ListDatabases.FocusedNode, 0]; except - on E:Exception do LogSQL(E.Message, lcError); + on E:EDatabaseError do LogSQL(E.Message, lcError); end; end; diff --git a/source/mysql_connection.pas b/source/mysql_connection.pas index 04fcef58..d244b5fa 100644 --- a/source/mysql_connection.pas +++ b/source/mysql_connection.pas @@ -41,6 +41,9 @@ type function Compare(const Left, Right: TDBObject): Integer; override; end; + // Custom exception class for any connection or database related error + EDatabaseError = class(Exception); + {$M+} // Needed to add published properties { TConnectionParameters and friends } @@ -350,7 +353,7 @@ begin {PansiChar(AnsiString(FParameters.CApath))}nil, {PansiChar(AnsiString(FParameters.Cipher))}nil); if SSLresult <> 0 then - raise Exception.CreateFmt('Could not connect using SSL (Error %d)', [SSLresult]); + raise EDatabaseError.CreateFmt('Could not connect using SSL (Error %d)', [SSLresult]); end; end; @@ -387,10 +390,10 @@ begin WaitForSingleObject(FPlinkProcInfo.hProcess, 1000); GetExitCodeProcess(FPlinkProcInfo.hProcess, ExitCode); if ExitCode <> STILL_ACTIVE then - raise Exception.Create('PLink exited unexpected. Command line was:'+CRLF+PlinkCmd); + raise EDatabaseError.Create('PLink exited unexpected. Command line was:'+CRLF+PlinkCmd); end else begin ClosePlink; - raise Exception.Create('Couldn''t execute PLink: '+CRLF+PlinkCmd); + raise EDatabaseError.Create('Couldn''t execute PLink: '+CRLF+PlinkCmd); end; FinalHost := 'localhost'; FinalPort := FParameters.SSHLocalPort; @@ -436,7 +439,7 @@ begin FConnectionStarted := 0; FHandle := nil; ClosePlink; - raise Exception.Create(Error); + raise EDatabaseError.Create(Error); end else begin Log(lcInfo, 'Connected. Thread-ID: '+IntToStr(ThreadId)); FActive := True; @@ -515,7 +518,7 @@ begin if querystatus <> 0 then begin // Most errors will show up here, some others slightly later, after mysql_store_result() Log(lcError, GetLastError); - raise Exception.Create(GetLastError); + raise EDatabaseError.Create(GetLastError); end else begin // We must call mysql_store_result() + mysql_free_result() to unblock the connection // See: http://dev.mysql.com/doc/refman/5.0/en/mysql-store-result.html @@ -527,7 +530,7 @@ begin // Indicates a late error, e.g. triggered by mysql_store_result(), after selecting a stored // function with invalid SQL body. Also SHOW TABLE STATUS on older servers. Log(lcError, GetLastError); - raise Exception.Create(GetLastError); + raise EDatabaseError.Create(GetLastError); end; if Result <> nil then begin FRowsFound := mysql_num_rows(Result); @@ -1473,7 +1476,7 @@ begin else Result := String(AnsiStr); end else if not IgnoreErrors then - Raise Exception.CreateFmt('Column #%d not available. Query returned %d columns and %d rows.', [Column, ColumnCount, RecordCount]); + Raise EDatabaseError.CreateFmt('Column #%d not available. Query returned %d columns and %d rows.', [Column, ColumnCount, RecordCount]); end; @@ -1485,7 +1488,7 @@ begin if idx > -1 then Result := Col(idx) else if not IgnoreErrors then - Raise Exception.CreateFmt('Column "%s" not available.', [ColumnName]); + Raise EDatabaseError.CreateFmt('Column "%s" not available.', [ColumnName]); end; @@ -1503,7 +1506,7 @@ begin BinToHex(FCurrentRow[Column], PChar(Result), BinLen); end; end else if not IgnoreErrors then - Raise Exception.CreateFmt('Column #%d not available. Query returned %d columns and %d rows.', [Column, ColumnCount, RecordCount]); + Raise EDatabaseError.CreateFmt('Column #%d not available. Query returned %d columns and %d rows.', [Column, ColumnCount, RecordCount]); end; diff --git a/source/routine_editor.pas b/source/routine_editor.pas index d7301fa0..4226d86c 100644 --- a/source/routine_editor.pas +++ b/source/routine_editor.pas @@ -460,7 +460,7 @@ begin btnDiscard.Enabled := Modified; Mainform.actRunRoutines.Enabled := True; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOk], 0); Result := mrAbort; end; diff --git a/source/table_editor.pas b/source/table_editor.pas index e6c3c8d4..ae5cce7b 100644 --- a/source/table_editor.pas +++ b/source/table_editor.pas @@ -405,7 +405,7 @@ begin AlterCodeValid := False; CreateCodeValid := False; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOk], 0); Result := mrAbort; end; diff --git a/source/tabletools.pas b/source/tabletools.pas index 386c10c8..bbdc21bb 100644 --- a/source/tabletools.pas +++ b/source/tabletools.pas @@ -474,15 +474,10 @@ begin Views.Add(DBObj) else ProcessNodeFunc(DBObj); - except + except on E:EDatabaseError do // The above SQL can easily throw an exception, e.g. if a table is corrupted. // In such cases we create a dummy row, including the error message - on E:Exception do begin - if E.ClassType = EAccessViolation then - Raise - else - AddNotes(DBObj.Database, DBObj.Name, 'error', E.Message); - end; + AddNotes(DBObj.Database, DBObj.Name, 'error', E.Message) end else begin AddNotes(DBObj.Database, DBObj.Name, STRSKIPPED+FormatByteNumber(DBObj.Size), ''); end; @@ -494,7 +489,7 @@ begin for i:=0 to Views.Count-1 do begin try ProcessNodeFunc(Views[i]); - except on E:Exception do + except on E:EDatabaseError do AddNotes(Views[i].Database, Views[i].Name, 'error', E.Message); end; end; @@ -798,7 +793,7 @@ begin comboExportOutputTarget.ItemIndex := 0; Screen.Cursor := crDefault; except - on E:Exception do begin + on E:EDatabaseError do begin Screen.Cursor := crDefault; MessageDlg(E.Message, mtError, [mbOK], 0); comboExportOutputType.ItemIndex := FLastOutputSelectedIndex; @@ -1123,7 +1118,7 @@ begin Struc := fixNewlines(Struc); Output(Struc, True, True, True, True, True); except - On E:Exception do begin + on E:EDatabaseError do begin // Catch the exception message and dump it into the export file for debugging reasons Output('/* '+E.Message+' */', False, True, True, False, False); Raise; diff --git a/source/trigger_editor.pas b/source/trigger_editor.pas index 2aa435c0..7af80d7d 100644 --- a/source/trigger_editor.pas +++ b/source/trigger_editor.pas @@ -179,7 +179,7 @@ begin btnSave.Enabled := Modified; btnDiscard.Enabled := Modified; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Result := mrAbort; end; diff --git a/source/updatecheck.pas b/source/updatecheck.pas index dfb09e51..6485c335 100644 --- a/source/updatecheck.pas +++ b/source/updatecheck.pas @@ -128,7 +128,7 @@ begin MainReg.WriteString(REGNAME_LAST_UPDATECHECK, DateTimeToStr(Now)); except // Do not popup errors, just display them in the status label - On E:Exception do + on E:Exception do Status(E.Message); end; if FileExists(CheckfileDownload.Filename) then diff --git a/source/usermanager.pas b/source/usermanager.pas index 57ab2158..823faccc 100644 --- a/source/usermanager.pas +++ b/source/usermanager.pas @@ -311,7 +311,7 @@ begin except // At least one priv table is missing or non-accessible when we get an exception. // Proceeding would result in follow up errors, so cancel the whole dialog in that case. - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message+CRLF+CRLF+'The user manager cannot proceed with this error.', mtError, [mbOK], 0); PostMessage(Handle, WM_CLOSE, 0, 0); Exit; @@ -928,7 +928,7 @@ begin Mainform.Connection.Query(sql + mask(PRIVTABLE_DB) + AcctWhere); Mainform.Connection.Query(sql + mask(PRIVTABLE_USERS) + AcctWhere); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -965,7 +965,7 @@ begin Mainform.Connection.Query(sql + mask(PRIVTABLE_TABLES) + AcctValues + AcctWhere); Mainform.Connection.Query(sql + mask(PRIVTABLE_COLUMNS) + AcctValues + AcctWhere); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1010,7 +1010,7 @@ begin try Mainform.Connection.Query(sql + mask(PRIVTABLE_USERS) + AcctValues + AcctWhere); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1055,7 +1055,7 @@ begin // Todo: Allow concurrency by skipping this account and removing from Users array if inserting key in mysql.user fails. Mainform.Connection.Query(sql); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1124,7 +1124,7 @@ begin try Mainform.Connection.Query(sql + AcctWhere); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1136,7 +1136,7 @@ begin try Mainform.Connection.Query(sql + AcctWhere + PrivWhere); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1204,7 +1204,7 @@ begin if Mainform.Connection.RowsAffected = 0 then Mainform.Connection.Query('UPDATE ' + db + '.' + TableName + ' SET ' +Delim(PrivUpdates) + AcctWhere); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1229,7 +1229,7 @@ begin try Mainform.Connection.Query(sql); except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; @@ -1241,7 +1241,7 @@ begin Mainform.Connection.Query('FLUSH PRIVILEGES'); ModalResult := mrOK; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; end; diff --git a/source/view.pas b/source/view.pas index ce00ae9e..467af2fa 100644 --- a/source/view.pas +++ b/source/view.pas @@ -186,7 +186,7 @@ begin btnSave.Enabled := Modified; btnDiscard.Enabled := Modified; except - on E:Exception do begin + on E:EDatabaseError do begin MessageDlg(E.Message, mtError, [mbOk], 0); Result := mrAbort; end;