Оператор Try . Except . Finally . End; при работе с ресурсами
Задача такая. Есть текстовый файл в ресурсах, который считывается и записывается в Memo. Требуется предусмотреть обработку ошибки на случай, если файла с таким именем в ресурсе нет.
Delphi
Delphi
Вроде всё делаю по инструкции.
Подскажите, пожалуйста, где ошибка?
Заранее спасибо за ответ(ы).
31.03.2019, 08:47
Почему конструкция try finally end все равно выдает сообщение об ошибке? Почему при использовании конструкции try .. except end; при возникновении ошибки программа.
оператор read при работе с графикой. мне надо присвоить значение переменной с с клавиатуры. компиляция проходит успешно но после того.
Не получается перегрузить оператор ++ при работе с массивами Текст: #include #include using namespace std; class array < .
Где почитать о работе с ресурсами в WinAPI и Visual Studio? Интересует работа с .gif и картинками. Хочу научиться добавлять их в приложение и уметь выгружать.
31.03.2019, 11:06
2
Дело не в инструкции, а в лени. Если б ты в отладчике прогнал этот кусок пошагово, то и на форуме терять время не пришлось.
Думаю, что исключение возникает в блоке finally на строке
Delphi
31.03.2019, 11:33 [ТС]
3
Прогнал и в отладчике до обращения в форум.
Исключение возникает на операторе:
Delphi
Так и должно быть, ибо специально смоделирована ситуация, когда ресурс с именем ResName не существует. Иными словами, этим оператором делается попытка обратиться к не существующему ресурсу.
Добавлено через 13 минут Хотелось, что бы отлавливалась ошибка, гасилось сообщение об ошибке и дальше функция возвращает строку с заранее сформированным сообщением.
Delphi
Вроде работает, как надо.
Остался вопрос вот в чём. Если ресурс с именем ResName не существует, то при выполнении оператора:
Delphi
31.03.2019, 11:34
4
Delphi
31.03.2019, 11:38 [ТС]
5
Delphi
Delphi
31.03.2019, 11:41
6
Delphi
31.03.2019, 11:44 [ТС]
7
Delphi
Delphi
возникла ошибка, дальше управление передано в блок except и всё, что ниже ResStream := TResourceStream.Create. не выполняется.
Посему — я зря включил блок finally?
Добавлено через 37 секунд
31.03.2019, 11:48
8
Я пишу подобные функции, которые возвращают тип boolean, а сообщение об ошибке показывают внутри себя, а не выдают его наружу.
Это мой личный подход. Никому не навязываю.
31.03.2019, 12:36
9
таким подходом избаевляешься от паразитных связей, раньше тоже пытался извращаться, когда надо было вернуть несколько значений. лепил структуру и прочее, чтобы сделать возврат, но это было в период неустойчивости меня в программировании, потом наступают некие устоявшиеся состояния, которым ты придерживаешься ))
так же у меня не устоялось (возможно еще) использование try expect/finally, как-то вот получается всегда обходить их, даже не целенаправленно, а по ходу логики программы, не лепя даже костылей при этом.
а вот один знакомый у меня есть, он наоборот ведет логику к тому, чтобы было это исклчюение, чтобы поймать некий случай)) выглядит дико для меня как-то.
Delphi try finally
Try используется следующими способами:
В конструкции Try-Finally, инструкция Finally гарантированно выполнится, абсолютно независимо оттого, что произойдет в предложении Try. Однако, предложение Finally фактически не обрабатывает никаких исключений — программа закончится, если никаких пунктов Except не найдено (см. примечания ниже).
Try-Finally обычно используется подпрограммой для гарантированной очистки, например освобождения ресурсов.
В этой версии, раздел Exept будет выполнен, только если предложение Try сгенерирует исключение. Это используется для принятия альтернативных действий, когда что-нибудь идет не так, как надо. Пункт except не может определить тип ошибки.
Она подобно версии 2, но определяет различные действия для различных типов исключений, таких как EInOutError. Пункт Else может использоваться как ловушка всех неопределенных типов исключений. Общий тип исключений Exception может использоваться для захвата всех типов исключений.
По назначенному имени (Name) исключения, можно получить текст сообщения исключения (Name.Message) для его отображения или других использований.
Если исключение не обработано инструкциями On или Else (для 3 версии), то выполняется проверка, находимся ли мы во вложенном блоке Try. Если да, то обрабатывается пункт Except своего родительского Try.
Пункт Else не является, действительно необходимым, лучше использовать On E:Exception Do являющееся универсальной обработкой особых ситуаций, так как обеспечивает сообщение об ошибке (E.Message).
Важно: вы можете определить тип ошибки, которая произошла, при использовании универсальной обработки особых ситуаций — On E:Exception Do. E это указатель на объект исключения. E.ClassName дает тип исключения, такой как ‘EDivByZero‘, как показано в последнем примере.
Следующий список исключений охватывает основные типы — всего имеется сотни классов исключения:
Exception Базовый класс EAbort Аварийное завершение работы без диалогового окна EAbstractError Абстрактная ошибка метода AssertionFailed Утверждают неудавшийся запрос EBitsError Булев массив ошибок ECommonCalendarError Календарная ошибка EDateTimeError Ошибка DateTime EMonthCalError Ошибка месяца EConversionError Вызывается Convert EConvertError Ошибка конвертирования объекта EDatabaseError Ошибка базы данных EExternal Ошибка аппаратных средств/Windows EAccessViolation Нарушение прав доступа EControlC Произошло аварийной завершение работы пользователем EExternalException Другая Внутренняя ошибка EIntError Целочисленная ошибка EDivByZero Деление на ноль EIntOverflow Переполнение целого числа ERangeError Вне диапазона значений EMathError Ошибка с плавающей запятой EInvalidArgument Плохое значение аргумента EInvalidOp Несоответствующая операция EOverflow Значение слишком большое EUnderflow Значение слишком маленькое EZeroDivide Деление на ноль EStackOverflow Серьёзная проблема Delphi EHeapException Проблемы динамической памяти EInvalidPointer Плохой указатель памяти EOutOfMemory Нет возможности распределить память EInOutError Ошибка ввода/вывода EInvalidCast Ошибка произведенная объектом EInvalidOperation Плохая операция компонента EMenuError Ошибка пункта меню EOSError Ошибка операционной системы EParserError Ошибка синтаксического анализа EPrinter Ошибка принтера EPropertyError Ошибка свойства класса EPropReadOnly Недопустимое обращение к свойству EPropWriteOnly Недопустимое обращение к свойству EThread Ошибка потока EVariantError Различная ошибка
Примечания
Иногда Вы хотите построить конструкцию подобно этому:
где исключения заманены в ловушку и обработаны, но в любом случае, набор инструкций очистки будут выполнены. Это может быть достигнуто с помощью вложенных инструкций Try:
Try Try . Except . End; Finally . End;
Похожие команды
Except Начинает предложение заманивающее в ловушку ошибки Try инструкции
Finally Начинает безоговорочный раздел кода инструкции Try
On Определяет обработку особых ситуаций в предложении TryExcept
Delphi try finally
try is used in a number of ways.
In a Try-Finally construct, the Finally statement is guaranteed to be executed absolutely regardless of what happens in the try clause. However, the Finally clause does not actually handle any exceptions — the program will terminate if no Except clause is found (see notes below).
Try-Finally is normally used by a routine to allow cleanup processing to take place, such as freeing resources, with the exception being correctly passed to the caller to handle.
In this version, only if the try clause generates an exception will the Except clause be executed. This is used to take alternative action when something unexpected goes wrong. The except clause cannot determine the error type however.
This is similar to version 2, but specifies different actions for different exception types, such as EInOutError. An Else clause can be used as a catch all for unexpected exception types. The general exception type Exception can be used to catch all exception types.
By assigning a Name to the exception, the message text of the exception (Name.Message) can be obtained for display or other uses.
When an exception is raised in a version 3 setup, if the exception is not acted upon by On or Else statements, then a check is made to see if we are in a nested Try block. If so, the Except clause of this parent Try is processed. If no On or Else clause is found, the program terminates.
The Else clause is not really necessary — it is better to use On E:Exception Do, the generic exception handling, since it still provides the error message (E.Message).
Important : you can determine the type of error that occured by using the generic exception handling — On E:Exception Do. E is a pointer to the exception object that is created by the exception condition. E.ClassName gives the exception type, such as ‘EDivByZero’, as shown in the final example code.
The following list of exceptions covers the basic types — there are hundreds of exception classes:
Exception
Base class
EAbort
Abort without dialog box
EAbstractError
Abstract method error
AssertionFailed
Assert call failed
EBitsError
Boolean array error
ECommonCalendarError
Calendar calc error
EDateTimeError
DateTime calc error
EMonthCalError
Month calc error
EConversionError
Raised by Convert
EConvertError
Object convert error
EDatabaseError
Database error
EExternal
Hardware/Windows error
EAccessViolation
Access violation
EControlC
User abort occured
EExternalException
Other Internal error
EIntError
Integer calc error
EDivByZero
Divide by zero
EIntOverflow
Integer overflow
ERangeError
Out of value range
EMathError
Floating point error
EInvalidArgument
Bad argument value
EInvalidOp
Inappropriate operation
EOverflow
Value too large
EUnderflow
Value too small
EZeroDivide
Divide by zero
EStackOverflow
Severe Delphi problem
EHeapException
Dynamic memory problem
EInvalidPointer
Bad memory pointer
EOutOfMemory
Cannot allocate memory
EInOutError
IO error
EInvalidCast
Object casting error
EInvalidOperation
Bad component op
EMenuError
Menu item error
EOSError
Operating system error
EParserError
Parsing error
EPrinter
Printer error
EPropertyError
Class property error
EPropReadOnly
Invalid property access
EPropWriteOnly
Invalid property access
EThread
Thread error
EVariantError
Variant problem
Notes
There are times when you want a construct like this :
where exceptions are trapped and acted upon, but in all cases, a set of clean up statements are executed. This can be achieved with nested try statements :
Образовательный блог — всё для учебы
Программы Delphi имеют встроенную обработку исключений по умолчанию, которая в некоторых случая может оказаться достаточной. встроенная обработка исключений преследует, во-первых, получение более подробной информации об ошибке и/или месте ее возникновения и, во-вторых, включение собственного кода по ее обработке, если стандартная обработка не устраивает.
Чтобы заставить программы на Delphi использовать механизм управления исключениями, необходимо разместить соответствующие операторы внутри специальных языковых конструкций Try.
Конструкция Try .. Finally .. End
Конструкция Try..Finally гарантирует, что программа выполнит операторы, освобождающие ресурсы, независимо от того, было или нет возбуждено исключение. Таким образом, эта конструкция используется тогда, когда вполне достаточным является просто безопасно завершить программу после возникновения исключения. Исключения в таких конструкциях не обрабатываются, их обработка будет передана далее. Если другой обработки не предусмотрено, то управление будет передано обработчику по умолчанию.
Синтаксис конструкции следующий:
Try Finally End;
Следует отметить, что, если исключение не будет возбуждено, то операторы из раздела Finally также будут освобождать ресурсы. Отличие заключается в том, что: • во-первых, при возникновении исключения часть операторов из раздела Try не выполняется, а при нормальной работе — выполняются все; • во-вторых, после освобождения ресурсов вследствие возбуждения исключения поиск обработчика исключения продолжится, поскольку исключения этой конструкцией не обрабатываются, а при нормальной работе будет выполняться оператор, следующий за конструкцией Try..Finally. Следует по возможности получать различные ресурсы перед конструкцией Try. Это гарантирует, что раздел Finally сможет должным образом освободить ресурсы.
Операторы в разделе Except выполняются только при возбуждении исключений, но никогда при нормальной работе программы. Более того, в разделе Except может быть несколько обработчиков исключений, каждый из которых ориентирован на определенный тип исключения. После выполнения операторов из раздела Except исключения уничтожаются, а выполнение программы продолжается с оператора, следующего за конструкцией Try..Except.
Синтаксис конструкции следующий:
Try Except End;
Как и ранее, операторы раздела Try могут возбуждать исключения. Раздел Except содержит операторы, которые выполняют действия по очистке (cleanup code, termination code). Однако если ошибка не возникает, то операторы из раздела Except пропускаются.
Операторы раздела Try в обеих конструкциях называются защищенным кодом.
Вложенные конструкции Try
Delphi позволяет использовать вложенные конструкции обработчиков исключений. Глубина вложения и последовательность следования конструкций не ограничена. Общий синтаксис вложенных конструкций Try:
Try Try Exceptionally End; Except|Finally End;
Так, поскольку конструкция Try..Finally в действительности не обрабатывает исключения, то, заключив ее внутрь конструкции Try..Except, мы с помощью конструкции Try..Finally можем возвратить ресурсы системе, а уже затем с помощью конструкции Try..Except обработать исключение.