Delphi не выводить сообщение об ошибке


Перехват ошибок SQL на Delphi в ADOConnection

Перехват ошибок SQL на Delphi при работе с компонентом ADO

Механизм, как «запретить — разрешить» выводить сообщение об ошибке подключения программы на Delphi через SQL через компонент TADOConnection.

Типичная обработка ошибки заключается в том, чтобы обрамить блоки кода в конструкции try..except или try..finally. Однако, многие попросту не делают этого, так как им недосуг или обработка исключений оставляется «на потом».

Чтобы не выводить сообщения об ошибке можно написать такой код, используя конструкцию «try-finally»:

procedure TAnswerList.Update(ADO : TADOQuery);
begin
with ADO do
begin
if Active then Close;
SQL.Text:=concat('UPDATE ANSWER_LIST SET ',
'NAME = "', self.Name, ', ',
'NOMER_ID = "', IntToStr(self.Nomer), ', ',
'CREDITOR_ID = "', IntToStr(self.CreditorId), ' ',
'WHERE ID = ' + IntToStr(self.id));
try
ExecSQL;
finally
end;
end;
end;

Чтобы грамотно вывести сообщение об ошибке можно использовать другую конструкцию:

procedure TAnswerList.Update(ADO : TADOQuery);
begin
with ADO do
begin
if Active then Close;
SQL.Text:=concat('UPDATE ANSWER_LIST SET ',
'NAME = "', self.Name, ', ',
'NOMER_ID = "', IntToStr(self.Nomer), ', ',
'CREDITOR_ID = "', IntToStr(self.CreditorId), ' ',
'WHERE ID = ' + IntToStr(self.id));
try
ExecSQL;
except
On E:Exception Do
begin
ShowMessage(concat('Update answer list failure. ',e.Message,#13#10,SQL.Text));
Exit;
end;
end;
end;

Как вариант, Вы можете использовать свойство Application.OnException, которое является глобальным обработчиком событий приложения. 

Для этого предлагается оформить обработку исключений в отдельный компонент.

unit sExceptionsCatcher;


{***} interface {***}

uses Classes, SysUtils, JPEG;

type
  TsExceptionsCatcher = class(TComponent)
  private
    FEnabled: boolean;
    FGenerateScreenshot: boolean;
    FJPEGScreenshot: boolean;
    FJpegQuality: TJPEGQualityRange;
    FCollectInfo: boolean;
    Fn: TFilename;
    procedure SetEnabled(const Value: boolean);
    { Private declarations }
  protected
    { Protected declarations }
    procedure EnableCatcher;
    procedure DisableCatcher;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Catcher(Sender: TObject; E: Exception);
  published
    { Published declarations }
    property Enabled: boolean read FEnabled write SetEnabled
                      default False;
  end;

procedure Register;

{***} implementation {***}

uses Windows, Forms, Dialogs, Graphics;

procedure Register;
begin
  RegisterComponents('Catch Exceptions', [TsExceptionsCatcher]);
end;

{ TsExceptionsCatcher }
constructor TsExceptionsCatcher.Create(AOwner: TComponent);
begin
  inherited;
end;

destructor TsExceptionsCatcher.Destroy;
begin
  DisableCatcher;
  inherited;
end;

procedure TsExceptionsCatcher.SetEnabled(const Value: boolean);
begin
  FEnabled := Value;
  if Enabled then EnableCatcher else DisableCatcher;
end;

procedure TsExceptionsCatcher.DisableCatcher;
begin
  Application.OnException := nil;
end;

procedure TsExceptionsCatcher.EnableCatcher;
begin
  Application.OnException := Catcher;
end;

procedure TsExceptionsCatcher.Catcher(Sender: TObject; E: Exception);
begin
  {TODO: Write some exception handling code}
end;

end.

Реализация функций 

// скриншот активного окна
procedure TsExceptionsCatcher.DoGenerateScreenshot;
var bmp: TBitmap;
    jpg: TJPEGImage;
begin
  bmp := Screen.ActiveForm.GetFormImage;
  begin
    jpg := TJPEGImage.Create;
    jpg.CompressionQuality := 100;
    jpg.Assign(bmp);
    jpg.SaveToFile(fn+'.jpg');
    FreeAndNil(jpg);
  end;
  FreeAndNil(bmp);
end;
// отчет, в котором будут указаны имя компьютера и имя текущего пользователя
function TsExceptionsCatcher.CollectUserName: string;
var
  uname: pchar;
  unsiz: cardinal;
begin
  uname := StrAlloc(255);
  unsiz := 254;
  GetUserName(uname,unsiz);
  if (unsiz > 0) then
    Result := string(uname) else
    Result := 'n/a';
  StrDispose(uname);
end;

function TsExceptionsCatcher.CollectComputerName: string;
var
  cname: pchar;
  cnsiz: cardinal;
begin
  cname := StrAlloc(MAX_COMPUTERNAME_LENGTH + 1);
  cnsiz := MAX_COMPUTERNAME_LENGTH + 1;
  GetComputerName(cname,cnsiz);
  if (cnsiz > 0) then
    Result := string(cname) else
    Result := 'n/a';
  StrDispose(cname);
end;
// Процедура создает объект класса TStringList, наполняет его информацией, которую надо записать и сохраняет в файл, 
// с именем, аналогичном имени файла со скриншотом
procedure TsExceptionsCatcher.DoCollectInfo(E: Exception);
var sl: TStringList;
begin
  sl := tstringlist.Create;
  sl.add('--- This report is created by automated '+
         'reporting system.');
  sl.add('Computer name is: ['+ComputerName+']');
  sl.add('User name is: ['+UserName+']');
  sl.add('--- End of report ----------------------'+
         '-----------------');
  sl.SaveToFile(Fn+'.txt');
end;

Дата публикации: 2015-05-12 10:36:28

 
Ануфрий
 
(2007-08-03 19:30)
[0]

С некоторых пор Дельфи стал показывать сообщения об ошибках (исключениях), которые пойманы через try.

Т.е. код до этого
try
 I := деление на ноль;
finally
end

Приводил к тому, что в режиме отладки дельфи сообщал об ошибке, и после нажатия F9 программа дальше работала. Без дельфи прога вообще ничего не выдавала.
Теперь показывается сообщение дельфи и после F9 вылетает MessageBox.
А если запускать без дельфи, то просто вылетает MessageBox (типа деление на ноль).
Раньше все было нормально, не пойму что случилось и как это убрать.


 
Dib@zol ©
 
(2007-08-03 19:32)
[1]

А может просто не делить на ноль??? Или это просто такой пример?


 
Ануфрий
 
(2007-08-03 19:35)
[2]

Это пример.


 
Anatoly Podgoretsky ©
 
(2007-08-03 19:39)
[3]

> Ануфрий  (03.08.2007 19:35:02)  [2]

В этом примере не делить на ноль.


 
Ануфрий
 
(2007-08-03 19:42)
[4]

Ну тогда другой пример.

var
 HTTP: TIdHTTP;
 Str: string;
begin
 HTTP := TIdHTTP.Create(nil);
 try
   Str := HTTP.Get("http://my_domain.com");
 finally
   HTTP.Free;
 end;
end;

При запуске вызывается исключение (сайт не найден). Мне нужно чтобы на экран не выдавалось сообщение с текстом исключения.


 
Dib@zol ©
 
(2007-08-03 19:43)
[5]

var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
  Str := HTTP.Get(«http://my_domain.com»);
finally
  HTTP.Free;
end;
end;

try..finally заменяй на try..except.


 
Anatoly Podgoretsky ©
 
(2007-08-03 19:45)
[6]

> Ануфрий  (03.08.2007 19:42:04)  [4]

Чтобы на экран не выдавалось сообщение, исключение надо обработать самому, это блок try except end


 
Anatoly Podgoretsky ©
 
(2007-08-03 19:46)
[7]

> Dib@zol  (03.08.2007 19:43:05)  [5]

try..finally убирать нельзя, это будет уже другая ошибка дизайна, например утечка как минимум


 
Ануфрий
 
(2007-08-03 19:49)
[8]

Dib@zol
Спасибо, работает. Хотя я всегда думал, что finally также «поглощает» ошибки, как except, только в отличие от последнего вызывается всегда, даже если ошибок нет. И вроде бы так и работало… Может просто не разу ошибок не попадалось внутри try finally end;


 
Ануфрий
 
(2007-08-03 19:52)
[9]

Anatoly Podgoretsky
Так нужно делать вложенные try что-ли?
var
HTTP: TIdHTTP;
Str: string;
begin
HTTP := TIdHTTP.Create(nil);
try
  try
    Str := HTTP.Get("http://my_domain.com");
  except
  end;
finally
  HTTP.Free;
end;
end;

Тогда наверное проще заменить на
var
HTTP: TIdHTTP;
Str: string;
begin
 HTTP := TIdHTTP.Create(nil);
 try
   Str := HTTP.Get("http://my_domain.com");
 except
 end;
 HTTP.Free;
end;

?


 
Ануфрий
 
(2007-08-03 19:56)
[10]

Посмотрел старый код. Раньше у меня тоже было try finally end. И никогда ошибки на экран не выдавались.


 
Zagaevskiy ©
 
(2007-08-03 19:57)
[11]

Может ошибок там не было?


 
Инс ©
 
(2007-08-03 19:57)
[12]


> Тогда наверное проще заменить на

В данном конкретном случае можно, но вообще лучше 1-й вариант.


 
{RASkov} ©
 
(2007-08-03 19:58)
[13]

> [9] Ануфрий   (03.08.07 19:52)
> Тогда наверное проще заменить на
> var
> HTTP: TIdHTTP;
> Str: string;
> begin
> HTTP := TIdHTTP.Create(nil);
> try
>   Str := HTTP.Get(«http://my_domain.com»);
> except
> end;
> HTTP.Free;
> end;
> ?

Не верно!

var
HTTP: TIdHTTP;
Str: string;
begin
 HTTP := TIdHTTP.Create(nil);
 try
  try
   Str := HTTP.Get("http://my_domain.com");
  except
   ShowMessage("Произошла ошибка такая-то");
  end;
 finally
  HTTP.Free;
 end;
end;


 
Инс ©
 
(2007-08-03 19:58)
[14]


> [10] Ануфрий   (03.08.07 19:56)

Почитай Рихтера, у него отлично механизм исключений расписан.


 
Anatoly Podgoretsky ©
 
(2007-08-03 20:01)
[15]

> Ануфрий  (03.08.2007 19:52:09)  [9]

Для данного кода можно написать с одним блоком, но обычно код сложнее и

except
end

Лучше заменить на

except
 что то полезное.
end


 
Anatoly Podgoretsky ©
 
(2007-08-03 20:08)
[16]

> Anatoly Podgoretsky  (03.08.2007 20:01:15)  [15]

Хотя бы на

except
  on E.Exception do begin
//     variable := E.Message
//или
//     LOG(llCriticalLevel, «Ошибка HTTP.Get(http://my_domain.com) = » + E.Message);
  end;
end

Это позволит как минимум поставить точку останова для отладки.


 
Ануфрий
 
(2007-08-03 20:10)
[17]

Все, спасибо всем, просто заработался.


function GetBody(const URL: string): string;
var
 HTTP: TIdHTTP;
 Str: string;
begin
 Result := "";
 HTTP := TIdHTTP.Create(nil);
 try
   Result := HTTP.Get("http://my_domain.com");
 finally
   HTTP.Free;
 end;
end;

а далее вызов так

 try
   S := GetBody("http://domain.com");
 except
   S := "";
 end;

потому ошибки не было. А когда я начал разбираться с GetBody, видел только finally и это меня смутило, почему вдруг стали ошибки появляться. :)


 
Anatoly Podgoretsky ©
 
(2007-08-03 20:23)
[18]

> Ануфрий  (03.08.2007 20:10:17)  [17]

Вот это грамотный код.


At the moment I have a Delphi form running and upon losing connection to its Database/loss of network, it re-establishes and carries on.

The service is on a timer and each minute, it pops up with message box saying failure to connected to db on network [ip address]. This is at the start of the timer, a stored proc is ran.

I have all errors writing to a log file on the service local machine, is there a way I can suppress the message box appearing as I don’t need it to appear all the time? by message box it is a windows exception box not a showMessageBox(). It automatically pops up when the exception hits but it will continuously hit whilst the machine boots up and re-establishes connection to the network.

The code I have is as follows

    (*Call db Procedure*)
            try
              db.SQL.Clear;
              db.SQL.Add('call dbProc();');
              db.ExecSQL;
            except
              On E : Exception Do
              begin
                If E.ClassName = 'EIBInterBaseError' Then
                  begin
                    WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
                          + ' loop to catch up , please see user guide V.1.0.2.145',2);
                    reconnectdb;
                  end
                  else if E.ClassName = 'EADOError' then
                  begin
                    WriteToLog('Network Error : An error has occured whilst trying to communicate with the db outside the'
                          + ' loop to catch up , please see user guide V.1.0.2.145',2);
                    reconnectDB;
                  end;
                end;
            end;

Эксперт С++

476 / 444 / 34

Регистрация: 20.11.2009

Сообщений: 1,293

1

Отключить сообщение об исключении

08.07.2010, 13:52. Показов 4091. Ответов 7


Студворк — интернет-сервис помощи студентам

Если запускать приложение прямо в делфи, то когда происходит исключение, делфи благим матом орет об этом, даже если исключение отловлено. Это надоедает. Можно отключить? (Если просто запускать экзешник — все нормально)

Добавлено через 15 минут
Таки нагуглил.
http://edn.embarcadero.com/article/32015
Если кому надо: Tools -> Debugger Options -> снять галку со Stop on Delphi Exceptions.



0



КотЪ

219 / 219 / 60

Регистрация: 26.05.2009

Сообщений: 688

08.07.2010, 14:25

2

Если исключение возникает — значит ваша программа работает не так, как нужно или с ошибками.
Отключить уведомления — это всё-равно что лечить язву желудка болеутоляющими таблетками



0



Хохол

Эксперт С++

476 / 444 / 34

Регистрация: 20.11.2009

Сообщений: 1,293

08.07.2010, 14:37

 [ТС]

3

Я проверяю, введено ли в текстовое поле число — чето типа

Delphi
1
2
3
4
5
6
7
8
9
10
function isCorrect: boolean;
begin
try
   StrToInt(SomeEdit.text);
except
   result := false;
   exit;
end;
result := true;
end;

Конкретно в данном случае исключение не означает неправильной работы программы. И уж тем более мне не нужно сообщать об отловленном исключении.



0



VampireKB

36 / 35 / 3

Регистрация: 12.06.2009

Сообщений: 211

08.07.2010, 21:33

4

проблема знакомая,но я нашел более чёткое решение )

Delphi
1
2
3
4
5
6
var
a:string;
b:integer;
begin
if trystrtoint(edit1.text,b) = true then a:=edit1.text+'.00';
end;



1



Эксперт С++

476 / 444 / 34

Регистрация: 20.11.2009

Сообщений: 1,293

08.07.2010, 21:55

 [ТС]

5

О, спасибо, VampireKB, давно мне такой штуки не хватало



0



36 / 35 / 3

Регистрация: 12.06.2009

Сообщений: 211

08.07.2010, 22:06

6

я в своё время просто тоже с такой проблемой столкнулся..и было тупо влом нажимать на ОК после каждого try except-а



0



Хохол

Эксперт С++

476 / 444 / 34

Регистрация: 20.11.2009

Сообщений: 1,293

08.07.2010, 22:10

 [ТС]

7

Советую писать

Pascal
1
if trystrtoint(edit1.text,b) then a:=edit1.text+'.00';

может это ваш стиль, конечно, но некоторые удивляются, что так можно…



0



36 / 35 / 3

Регистрация: 12.06.2009

Сообщений: 211

09.07.2010, 00:08

8

Если учесть,что я самоучка ,и многих вещей не знаю,то простительно,надеюсь )



0



форум программистов

  • Главная
  • Исходники Delphi
  • Справочники Delphi
  • Книги Delphi
  • Основы Delphi
  • библиотека Delphi исходников
  • Форум
  • Блоги

Последние записи

  • PostgreSQL — чтение файла
  • Обязательное прикрепление изображений
  • Игра «Крестики-Нолики» на чистом HTML (без скриптов)
  • Динамическое создание массива TScrollBar
  • Как разместить форму в панель задач?
  • CMD скрипт, запустить из memo
  • Как проверить работу сессий на PHP
  • Как узнать дату окончания сертификата
  • Как передать значение во внешний JS-скрипт?
  • Определить количество знаков после запятой
  • .NET
  • ASP.NET
  • assembler
  • Basic
  • c/c++
  • CMS
  • Delphi
  • Gamedev — cоздание игр
  • HTML
  • iPhone
  • Java
  • JavaScript
  • Lazarus, Free Pascal
  • Linux
  • Pascal
  • Perl
  • Photoshop
  • php
  • Python
  • QT
  • Ruby
  • SEO
  • sql
  • VBA
  • Win Api
  • Windows
  • XML и XSLT
  • Администрирование ОС
  • Апгрейды
  • Архив
  • Безопасность
  • Блоги
  • Веб-аналитика
  • Железо
  • Журнал
  • Заметки
  • Имейдж
  • Интервью
  • Исходники
  • Микроконтроллеры
  • Новости
  • Общалка
  • Операционные системы
  • Пост-обзор
  • Профлитература
  • Рассылка
  • Реклама
  • си шарп
  • Советы
  • Софт
  • Статьи
  • Топик-обзор
  • Файлы

Интенсив по Python: Работа с API и фреймворками 24-26 ИЮНЯ 2022. Знаете Python, но хотите расширить свои навыки?
Slurm подготовили для вас особенный продукт! Оставить заявку по ссылке — https://slurm.club/3MeqNEk


Online-курс Java с оплатой после трудоустройства. Каждый выпускник получает предложение о работе

И зарплату на 30% выше ожидаемой, подробнее на сайте академии, ссылка — ttps://clck.ru/fCrQw


Купить рекламу на сайте за 1000 руб

пишите сюда — alarforum@yandex.ru

Да и по любым другим вопросам пишите на почту

пеллетные котлы
пеллетные котлы

пеллетный котел
Пеллетный котел Emtas

форум программистов

Наши форумы по программированию:

  • Форум Web программирование (веб)
    • Форум Python (питон)
    • Форум PHP (пхп)
    • Форум Perl (перл)
    • Форум Ruby (руби)
    • Форум JavaScript (яваскрипт)
    • Форум Ajax (аякс)
    • Форум SQL (эскюэл)
    • Форум HTML (хтмл)
    • Форум CSS (сиэсэс)
    • Форум XML (иксмл)
    • Форум JSON (джсон)
  • Delphi форумы
    • Форум Pascal (паскаль)
    • Форум Delphi (делфи)
  • Форумы C (Си)
    • Форум C++ (си плюс плюс)
      • Форум C++ Builder (си билдер)
      • Форум Visual C++ (визуал си)
    • Форум Qt (Кью Тэ)
    • Форум C# (си шарп)
  • Форум .NET Frameworks (точка нет фреймворки)
    • Форум .NET (точка нет)
    • Форум ASP.NET (асп нет)
    • Форум Windows Forms (виндовс формс)
    • Форум базы данных ADO.NET (адо нет)
    • Форум .NET Framework WPF, UWP, WinRT, XAML ()
  • Форум Java (джава)
    • Форум Java Android (джава андроид)
    • Форум Java web (джава веб)
    • Форум Kotlin (котлин)
  • Форум низкоуровневое программирование
    • Форум Assembler (ассемблер)
    • Форум WinApi (вин апи)
  • Форум VBA (вба)
    • Форум Excel (эксель)
    • Форум Word (ворд)
    • Форум Access (аксесс)
  • Форум OpenGL
  • Форум DirectX
  • Форум CAD проектирование
  • Форум по операционным системам
    • Форум по администрированию ОС
    • Форум по администрированию серверов и VDS
    • Форум Windows
    • Форум Ubuntu
    • Форум Android
  • Форум Software (Софт)
  • Форум Hardware (Компьютерное железо)

Понравилась статья? Поделить с друзьями:
  • Delphi вывести сообщение об ошибке
  • Delphi shellexecute коды ошибок
  • Delphi privileged instruction ошибка
  • Delphi idftp обработка ошибок
  • Delphi getlasterror текст ошибки