|
Вопрос # 3 674/ вопрос решён / |
|
Здравствуйте, эксперты!
Использую в секции initialization процедуру Assert. Как сделать, чтобы прежде чем сдохнуть приложение выдало моё сообщение, а не "Runtime error xx at xxxxxxxx".
 |
Вопрос задал: DNK (статус: Студент)
Вопрос отправлен: 22 января 2010, 15:15
Состояние вопроса: решён, ответов: 1.
|
Ответ #1. Отвечает эксперт: Вадим К
Здравствуйте, Ершов Денис!
если хочется свое сообщение, то просто надо его написать, где то так
Assert(Result = 0, 'Ошибка в алгоритме');
Но если хочется ещё и номер строки в файле узнать, и файл лога все это дело записать, то тогда надо регистрировать свой обработчик. подробности и примеры тут http://www.delphimaster.ru/articles/errors/index.html
 |
Ответ отправил: Вадим К (статус: Академик)
Время отправки: 22 января 2010, 15:43
Оценка за ответ: 5
Комментарий к оценке: Проблема не в незнании процедуры Assert, а в том, что в секции initialization некому обработать вызванное им исключение. В чем-то помогла статья, воспользовался заменой указателя AssertErrorProc. Найти бы такую же для переопределения процедур обработки исключений.
|
Мини-форум вопроса
Всего сообщений: 13; последнее сообщение — 29 января 2010, 15:10; участников в обсуждении: 5.
|
min@y™ (статус: Доктор наук), 23 января 2010, 09:52 [#1]:
Ты бы код показал, а то телепатор отключили за неуплату.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
vlsavkin (статус: 2-ой класс), 23 января 2010, 12:23 [#2]:
Возможно Вам нужна не процедура Assert, а просто обработка исключений? Сравните:
procedure TForm1.Button1Click(Sender: TObject);
var a:Single;
i:Integer;
begin
try
i:=0;
a:=5/i;
except
ShowMessage('Ошибка деления');
end;
end;
и
procedure TForm1.Button1Click(Sender: TObject);
var a:Single;
i:Integer;
begin
i:=0;
a:=5/i;
end;
Еще в таком случае удобно снять галочку Stop On Delphi Exceptions в Debugger Option, вкладка Language Exceptions, чтобы видеть сообщения об ошибках, как будет видеть их пользователь, без приостанавливания программы. Для отладки же конечно нужно оставлять ее включенной.
|
|
DNK (статус: Студент), 25 января 2010, 11:31 [#3]:
2min@y™: В программе порядка 66000 строк, плюс ветви. Вроде все понятно и без кода. Есть секции инициализации в некоторох модулях и нужно централизованно отловить в них исключения (пока модулей только 10 и процедуры них генерируют только EAssertionFailed).
Схемотично это выглядит так: 1)Основной модуль
unit RegeisterUnit;
intreface
function RegisterFormClass(code: byte; clazz: FormClass);
implementation
function RegisterFormClass;
begin
...
Assert(...);
end;
end.
2)Переферия
unit TestUnit;
type
TTetsForm = class (Form)
...
initialization
RegisterFormClass(TestCode, TTestForm);
end.
"Digital Networked Knight"
|
|
Вадим К (статус: Академик), 25 января 2010, 11:53 [#4]:
Я думаю, в данном случае оптимально будет отказаться от секции initialization. Почему?
- компилятор не гарантирует, в каком порядке он будет вызвать эти секции
- много переменных на данный момент находятся в неопределенном состоянии.
Лучше в основном коде сделать вызов, который пробежится и зарегистрирует всё.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
DNK (статус: Студент), 26 января 2010, 09:54 [#5]:
Порядок вызова не важен, все регистрируемые модули равнозначны. Я как раз и пытаюсь таким способом избавиться от "вызовов в основном коде, которые по чему-то там пробегаются и чего-то проверяют", ибо замучился со слиянием веток в SVN.
"Digital Networked Knight"
|
|
Вадим К (статус: Академик), 26 января 2010, 11:19 [#6]:
Слияние веток не причина уродовать код. В целом делается так
- пишется инстукция по модулям, как кто кого и когда вызывает, несоблюдение - выговор.
- каждый модуль предоставляет функцию/процедуру/метод установленного образца, которую он регистрирует в массиве функций (это в принципе уже есть в вышеприведенном коде). Но вот только за одним отличием - только регистрация и ничего больше. никаких проверок/чтения конфигов. А вот уже основной код берет массив функций и по порядку выполняет. Именно так в делфи сделана регистрация компонентов.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
DNK (статус: Студент), 26 января 2010, 15:54 [#7]:
А как получить этот массив функций?
"Digital Networked Knight"
|
|
Вадим К (статус: Академик), 26 января 2010, 16:26 [#8]:
посмотрите как в делфи устроено RegisterComponent
Галочка "подтверждения прочтения" - вселенское зло.
|
|
DNK (статус: Студент), 26 января 2010, 17:02 [#9]:
А что это? Не нахожу такого идентификатора.
"Digital Networked Knight"
|
|
Вадим К (статус: Академик), 26 января 2010, 17:13 [#10]:
маленькая поправочка RegisterComponents
Находиться в модуле Classes.pas
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Тамара (статус: Посетитель), 26 января 2010, 20:15 [#11]:
А если запустить через exeшник?
|
|
DNK (статус: Студент), 27 января 2010, 08:24 [#12]:
2Вадим К: То-то же. Не вижу, чем эта процедура мне поможет. Она просто проверяет, существует ли точка входа регистрации и запускает её. Список компонентов для процедуры задается программистом ручками, от чего я и пытаюсь избавиться.
"Digital Networked Knight"
|
|
DNK (статус: Студент), 29 января 2010, 15:10 [#13]:
В конечном итоге от assert отказался. Написал свою процедуру. procedure Fatality(assert: boolean; Msg: string);
begin
if not assert then begin
// Выводим сообщение
MessageBox(0, PChar(Msg), 'Фатальная ошибка', MB_OK + MB_ICONSTOP);
// Выходим из программы
ExitProcess(1);
end;
end; Стараюсь по возможности избегать исключений. Там где нет возможности: try
...
except
on E: Exception do
Fatality(false, E.message);
end;
"Digital Networked Knight"
|
13 мая 2011, 09:38: Статус вопроса изменён на решённый (изменил автор вопроса — DNK): Всё отлично работает. Испытано временем.
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|