Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];
ВнизExceptions. Можно ли получить полный контроль над ними? Найти похожие ветки
← →
Германн (2004-02-19 02:33) [0]Поясню. Есть ли нормальный вариант получить полный контроль над всеми исключениями? Имея в виду, что блоки try except/finally рассыпаны по всей VCL, а также по, возможно, использующимися сторонними компонетами. Т.е. есть ли (и какая) возможность обработки исключения в Дельфи приложении до обработки их в компонентах и функциях VCL+сторонние компоненты*
← →
TUser (2004-02-19 10:15) [1]А оно надо?
← →
Тимохов (2004-02-19 10:32) [2]
> Германн © (19.02.04 02:33)
Согласен с 1. Оно надо? По каким критериям ты будешь обрабатывать исключения в компоненте, который написал Вася Пупков? Позвонишь ему?
Может быть речь о другом - о логе исключений? Проясни ситуацию...
← →
Nikolay M. (2004-02-19 11:45) [3]Возможно, Application.OnException имеется ввиду?
А вообще про исключения копай в MSDN про Structured Exception Handling.
← →
y-soft (2004-02-19 11:55) [4]>Германн © (19.02.04 02:33)
А почему нет?
try..finally и try..except могут ведь быть и вложенными, вложенный обработчик в правильно написанном приложении не отменяет возникшего исключения. Если есть объект Application, то можно все перехватывать в Application.OnException, если нет - поместить в try..except весь код программы. Отдельные трудности - с перехватом возможных исключений в дополнительных потоках и секциях initialization...
Другое дело - как Вы воспользуетесь этим контролем...
← →
Германн (2004-02-19 13:55) [5]2 y-soft © (19.02.04 11:55) [4]
Из хелпа:
Use OnException to change the default behavior that occurs when an exception is not handled by application code.
Речь действительно идет в частности и о логе. Именно туда предполагается записывать все сообщения об ошибках. Но главное все таки в другом - убрать возможность появления окошек с сообщениями об ошибках, поскольку нажимать на кнопку ОК некому.
← →
Тимохов (2004-02-19 14:05) [6]Если сделаете обрабтку этого события и не будете в нем показывать окошко с кнопкой, которую некому нажимать, то само окошко не появится.
← →
Плохиш (2004-02-19 14:06) [7]>Германн © (19.02.04 13:55) [5]
Тогда, действительно Application.OnException.
← →
Германн (2004-02-19 14:23) [8]Увы Application.OnException ловит только "exception is not handled by application code."
← →
Тимохов (2004-02-19 14:39) [9]
> Германн © (19.02.04 14:23) [8]
Что значит "увы"?
Зачем Вам ловить исключения, которые обработаны? Тем более, если обработаны не в Вашем коде, а в стороннем компоненте.
← →
Verg (2004-02-19 14:39) [10]Значит получается. что в твоем приложении там, где возникают исключения
навтыканы
try
...........
..........
except
On E : Exception Aplication.ShowException(E);
// Или еще какая-то обработка типа ShowMessage
end;
Али как?
> [5] Германн © (19.02.04 13:55)
> 2 y-soft © (19.02.04 11:55) [4]
> Из хелпа:
> Use OnException to change the default behavior that occurs
> when an exception is not handled by application code.
>
> Речь действительно идет в частности и о логе. Именно туда
> предполагается записывать все сообщения об ошибках. Но главное
> все таки в другом - убрать возможность появления окошек
> с сообщениями об ошибках, поскольку нажимать на кнопку ОК
> некому.
← →
y-soft (2004-02-19 14:48) [11]>Германн © (19.02.04 13:55) [5]
Что могу сказать? Не используйте сторонних компонентов, которые ведут себя недопустимым для Вашей задачи образом. Возможно, они действительно ведут себя так, как сказал Verg © (19.02.04 14:39) [10], тогда без правки их кода не обойтись
P.S. IMHO лучше вообще не использовать сторонние компоненты без исходного кода
← →
Amoeba (2004-02-19 16:26) [12]
> IMHO лучше вообще не использовать сторонние компоненты без
> исходного кода
Несколько спорное утверждение. Есть очень качественные профессионально сделанные, библиотеки идущие с исходным кодом за деньги и бесплатно без исходников, но обычно в урезанном виде. Все ли готовы и могут платить за исходники? И всегда ли эти расходы окупятся?
← →
Digitman (2004-02-19 16:35) [13]
> Германн © (19.02.04 02:33)
VCL не исключает создание и использование доп.код.потоков
для целей отслеживания необработанных исключений в доп.код.потоках вышеупомянутое App.OnException не годится - этот механизм работает только для осн.код.потока
более того - необработанное в поточной ф-ции исключение ведет к непредсказуемым послежствиям, вплоть до краха процесса
← →
Плохиш (2004-02-19 16:53) [14]>Германн © (19.02.04 14:23) [8]
Если программа/компонент оказывают окошко с сообшением, то это нормальная обработка и то исключение, которое, возможно, этому предшествовало, уже обработано.
← →
y-soft (2004-02-19 17:18) [15]>Amoeba © (19.02.04 16:26) [12]
Несколько спорное утверждение. Есть очень качественные профессионально сделанные, библиотеки идущие с исходным кодом за деньги и бесплатно без исходников, но обычно в урезанном виде. Все ли готовы и могут платить за исходники? И всегда ли эти расходы окупятся?
Основываюсь исключительно на личном горьком опыте - обидно натыкаться на чужие ошибки, так что тут надо выбирать - бесплатность vs надежность...
А библиотеки писать мы и сами могем :)
← →
Германн (2004-02-22 02:03) [16]Во-первых, спасибо всем принявшим участие в данном обсуждении.
Во-вторых, высказался бы ранее, если бы был доступен delphimaster.
В-третьих, едучи на объект, после полудня 19.02.04 понял насколько я был глуп, точнее ничего не соображал, задавая этот вопрос.
То бишь я понял, что (кстати помятуя Verg © (19.02.04 14:39 [10])), у меня нет таких ситуаций. И все, что мне нужно - это обработать в OnException все необработанные ранее исключения, но с некоторой проверкой, как себя вести в зависимости от конкретной ситуации.
В-четвертых, отвечая на y-soft © (19.02.04 14:48) [11] - я никогда не использовал и не собираюсь использовать компоненты без исходников.
2 Digitman © (19.02.04 16:35) [13]
А вот это уже очень интересно. У меня пока только один поток, но для будущих целей - весьма! Спасибо. Сохраню данную страницу в свой архив.
Сие писал 21.02.04 в 02:27, но увы не смог отправить. То ли Delphimaster шалил, то ли мой провайдер.
Сейчас отправляю.
Но, учитывая возможность "многопоточности" дальнейшего развития приложения (см. Digitman © (19.02.04 16:35) [13]),
есть вопрос что и как следует сделать, чтобы обработать все исключения?
← →
KSergey (2004-02-22 10:17) [17]> Германн © (22.02.04 02:03) [16]
> есть вопрос что и как следует сделать, чтобы обработать
> все исключения?
Обязательно заключить код метода Execute в try..except
И не выпусякать исключения наружу.
← →
y-soft (2004-02-22 15:38) [18]Ну, все исключения в принципе перехватить нельзя, по крайней мере в программе на Delphi - например, не перехватываются исключения при инициализации RTL...
← →
Германн (2004-02-23 01:08) [19]2 KSergey © (22.02.04 10:17) [17]
Спасибо. Учту как только так сразу и если многопоточность понадобится в данном случае.
А, кстати, термин выпусякать выглядит очень эстетно! :)
2 y-soft © (22.02.04 15:38) [18]
Это я примерно себе представлял, но имхо вероятность таких исключений либо 100% либо "мизер". Первый вариант легко находится, второй меня пока мало интересует. Заказчик понимает, что "раз в год и палка стреляет", и что программ, которые работают вечно (вместе с операционкой и самим компьютером) - не существует. Пока что минимальное время работы программы без сбоев, которое он хочет получить ~1.5 месяца.
Еще раз спасибо всем принявшим участие.
← →
KSergey (2004-02-23 09:20) [20]> Германн © (23.02.04 01:08) [19]
> А, кстати, термин выпусякать выглядит очень эстетно! :)
Ачепятка...
← →
Германн (2004-02-25 01:48) [21]А я и не сомневался, поэтому и поставил смайлик. :) Просто очень понравилось "звучаение" сей ачепятки. :)
← →
Германн (2004-02-25 03:19) [22]Кстати "звучаение" - тоже очепятка. (первое "е" там явно лишнее). :)
← →
}|{yk (2004-02-25 11:02) [23]Сейчас дорабатываю чей-то код (достался мне без опознавательных знаков) который делает именно то, о чем ты спрашиваешь.
unit ErrorCatcher;
interface
uses Classes, SysUtils, JPEG, LinarBitmap,PNGLoader;
type
TClassRef = class of TObject;
TImageFormat = (JPG, BMP, PNG);
type TImageQuality = 1..100;
type
TErrorCatcher = class(TComponent)
private
FEnabled: boolean;
FGenerateScreenshot: boolean;
FImageQuality: TImageQuality;
FCollectInfo: boolean;
Fn: TFilename;
FImageFileMask: string;
FSuffix: string;
ClassRef: TClassRef;
FErrorLogName: TFileName;
FFolderScreenShoots: string;
FImageFormat: TImageFormat;
procedure SetEnabled(const Value: boolean);
function CollectUserName: string;
function CollectComputerName: string;
{ 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);
procedure DoGenerateScreenshot;
procedure DoCollectInfo(E: Exception);
published
{ Published declarations }
property Enabled: boolean read FEnabled write SetEnabled default False;
property GenerateScreenshot: boolean read FGenerateScreenshot write FGenerateScreenshot default False;
property ImageQuality: TImageQuality read FImageQuality write FImageQuality default 100;
property CollectInfo: boolean read FCollectInfo write FCollectInfo default False;
property UserName: string read CollectUserName;
property ComputerName: string read CollectComputerName;
property ErrorLogName: TFileName read FErrorLogName write FErrorLogName;
property FolderScreenShoots: string read FFolderScreenShoots write FFolderScreenShoots;
property ImageFNameMask: string read FImageFileMask write FImageFileMask nodefault;
property ImageFormat: TImageFormat read FImageFormat write FImageFormat default PNG;
end;
procedure Register;
implementation
uses Windows, Forms, Dialogs, Graphics;
procedure Register;
begin
RegisterComponents("Additional", [TErrorCatcher]);
end;
{ TErrorCatcher }
constructor TErrorCatcher.Create(AOwner: TComponent);
begin
inherited;
ImageQuality := 100;
end;
destructor TErrorCatcher.Destroy;
begin
DisableCatcher;
inherited;
end;
procedure TErrorCatcher.SetEnabled(const Value: boolean);
begin
FEnabled := Value;
if Enabled then EnableCatcher else DisableCatcher;
end;
procedure TErrorCatcher.DisableCatcher;
begin
Application.OnException := nil;
end;
procedure TErrorCatcher.EnableCatcher;
begin
Application.OnException := Catcher;
end;
procedure TErrorCatcher.Catcher(Sender: TObject; E: Exception);
begin
if Screen.ActiveForm <> nil then
begin
FSuffix := "_" + Screen.ActiveForm.Name +
FormatDateTime("_ddmmyyyy_hhnnss", Now()) +
"_error";
if GenerateScreenshot then DoGenerateScreenshot;
end
else Exit;
if CollectInfo then DoCollectInfo(E);
end;
procedure TErrorCatcher.DoGenerateScreenshot;
var bitmap: TBitmap;
begin
if Screen.ActiveForm = nil then
Exit;
bitmap := Screen.ActiveForm.GetFormImage;
try
case FImageFormat of
BMP:
bitmap.SaveToFile(FFolderScreenShoots + FImageFileMask + FSuffix + ".bmp");
JPG:
begin
with TJPEGImage.Create do
begin
CompressionQuality := ImageQuality;
Assign(bitmap);
SaveToFile(FFolderScreenShoots +"\"+ FImageFileMask + FSuffix + ".jpg");
Free();
end;
end;
PNG:
begin
with TLinearBitmap.Create do
try
GetFromTBitmap(bitmap);
SaveToFile(FFolderScreenShoots + FImageFileMask + FSuffix + ".png");
finally
Free;
end;
end;
end;
finally
FreeAndNil(bitmap);
end;
end;
function TErrorCatcher.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 TErrorCatcher.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;
procedure TErrorCatcher.DoCollectInfo(E: Exception);
var sl: TStringList;
ClassThree: string; {строка с деревом классов}
time: string;
begin
time := FormatDateTime("_dd.mm.yyyy_hh.nn.ss", now);
ClassThree := E.ClassName;
ClassRef := E.ClassType;
while ClassRef.ClassParent <> nil do
begin
ClassRef := ClassRef.ClassParent;
ClassThree := ClassRef.ClassName + " => " + ClassThree;
end;
sl := TStringList.Create;
if (FileExists(self.FErrorLogName)) then
sl.LoadFromFile(self.FErrorLogName);
sl.add("--- This report is created by automated reporting system at " + time);
sl.add("Computer name is: [" + ComputerName + "]");
sl.add("User name is : [" + UserName + "]");
sl.Add("ClassThree : [" + ClassThree + "]");
sl.Add("Message : [" + E.Message + "]");
sl.Add(time);
sl.add("--- End of report ---------------------------------------");
sl.SaveToFile(self.FErrorLogName);
end;
end.
Если здесь есть автор исходного кода, пусть отозвется
← →
Германн (2004-02-26 00:41) [24]2 }|{yk © (25.02.04 11:02) [23]
Спасибо за дополнительную инфу. Днем почитаю ее внимательно. Может поможет не изобретать заново какие-то детали велосипеда.
← →
Гаврила (2004-02-26 00:49) [25]Приведенный выше код - всего навсего обертка вокруг Application.OnException. На обработку не перехваченных блоком try-except ичключений он не повлияет, равно как и не повлияет на обработку исключений, возникших вне основного потока программы
← →
KSergey (2004-02-26 05:33) [26]Если не ошибаюсь, в Jedi есть еще более навороченый перехватчик, который даже стек вызовов раскручивает... Там и код прилагается...
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.012 c