- Получение общего списка свойств терминала и программы
- Номер сборки терминала
- Тип и лицензия программы
- Режимы работы терминала и программы
- Разрешения
- Проверка сетевых подключений
- Вычислительные ресурсы: память, диск, процессор
- Характеристики экрана
- Строковые свойства терминала и программы
- Настраиваемые свойства: лимит баров и язык интерфейса
- Привязка программы к свойствам среды исполнения
- Проверка состояния клавиатуры
- Проверка статуса и причины остановки MQL-программы
- Программное закрытие терминала и код возврата
- Обработка ошибок времени исполнения программы
- Пользовательские ошибки
- Управление отладкой
- Предопределенные переменные
- Предопределенные константы языка MQL5
Обработка ошибок времени исполнения программы
Любая программа, составленная достаточно корректно, чтобы компилироваться без ошибок, все равно не застрахована от ошибок во время работы. Они могут возникать как по недосмотру разработчика, так и вследствие непредвиденных обстоятельств, возникших в программной среде ("пропал" Интернет, кончилась память). Но не менее вероятна и ситуация, когда ошибка возникает из-за неправильного применения программы: ведь, документацию пользователи читают в последнюю очередь. Во всех этих случаях программа должна иметь возможность проанализировать суть проблемы и адекватно её обработать.
Каждая инструкция MQL5 является потенциальным источником ошибок выполнения, и если таковые случаются, терминал сохраняет в специальную переменную _LastError описательный код. Разумеется, анализировать код следует непосредственно после каждой инструкции, поскольку потенциальные ошибки в последующих инструкциях могут перезаписать это значение на свое.
Обратите внимание, что существует ряд критических ошибок, при возникновении которых выполнение программы немедленно прерывается:
- деление на ноль;
- выход индекса за пределы массива;
- использование некорректного указателя объекта;
Полный перечень кодов ошибок, и что они значат, приведен в документации.
В разделе Открытие и закрытие файлов мы уже обращались к проблеме диагностики ошибок в рамках написания полезного макроса PRTF. Там, в частности, был введен вспомогательный заголовочный файл MQL5/Include/MQL5Book/MqlError.mqh, в котором перечисление MQL_ERROR позволяет простым способом преобразовать цифровой код ошибки в её имя с помощью EnumToString.
enum MQL_ERROR
|
Здесь в качестве параметра X макроса E2S как раз должна выступать переменная _LastError или эквивалентная ей функция GetLastError.
int GetLastError() ≡ int _LastError
Функция возвращает код последней ошибки, произошедшей в инструкциях MQL-программы. Изначально, в отсутствие ошибок, значение равно 0. Разница между чтением _LastError и вызовом функции GetLastError — чисто синтаксическая (выбирайте подходящий вариант в соответствие с предпочтительным стилем).
Следует иметь в виду, что штатное безошибочное выполнение инструкций не сбрасывает код ошибки. Обращение к GetLastError также этого не делает.
Таким образом, если есть последовательность действий, из которых лишь одно выставит признак ошибки, этот признак будет возвращаться функцией и для последующих (успешных) действий. Например,
// _LastError = 0 по умолчанию
|
Такое поведение затруднило бы локализацию проблемного места, поэтому для сброса переменной _LastError в 0 существует отдельная функция ResetLastError.
void ResetLastError()
Функция устанавливает значение встроенной переменной _LastError в ноль.
Функцию рекомендуется вызывать перед любым действием, которое может привести к ошибке, и после которого планируется проводить анализ с помощью GetLastError.
Хорошим примером использования обеих функций является уже упомянутый макрос PRTF (файл PRTF.mqh). Напомним его код:
#include <MQL5Book/MqlError.mqh>
|
Задача макроса и обернутой в него функции ResultPrint, вывести в журнал переданное значение, текущий код ошибки и тут же очистить код ошибки. Таким образом, последовательное применение PRTF на ряде инструкций всегда гарантирует, что выведенная в журнал ошибка (или признак успеха) соответствует именно последней инструкции, с помощью которой было получено значение параметра retval.
Сохранение _LastError в промежуточной локальной переменной snapshot потребовалось по той причине, что _LastError может изменить свое значение практически в любом месте вычисления выражения, если какая-либо операция выполнится с ошибкой. В частности, здесь в макросе E2S используется функция EnumToString, которая может взвести свой код ошибки, если в качестве аргумента передано значение, отсутствующее в перечислении. Тогда в последующих частях того же выражения при формировании строки будет фигурировать уже не изначальная ошибка, а наведенная.
В любой инструкции может оказаться несколько мест, где _LastError вдруг изменится. В связи с этим желательно зафиксировать код ошибки сразу после интересующего нас действия.