API Basic OnError - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki

On Error / Resume

ClassicUO • Basic

On Error задаёт обработку последующих ошибок выполнения в текущей процедуре или функции. Это конструкция языка, а не вызываемая API-команда. Для структурированной обработки и завершения используйте Try/Catch/Finally.

Точный синтаксис

On Error GoTo label
On Error Resume Next
On Error GoTo 0
label:
Resume
Resume Next

Параметры

  • label — Существующая метка внутри той же процедуры, записанная отдельной строкой label:. Может стоять выше или ниже On Error, регистр букв не важен. Это не имя функции, строка в кавычках и не номер строки исходника. Неизвестная метка даёт SC009; клиент блокирует такой скрипт.
  • Resume Next / On Error — On Error Resume Next включает автоматическое продолжение после ошибочной инструкции без перехода к метке. Успешные инструкции работают обычно. Режим действует в текущем вызове процедуры, а не во всех скриптах.
  • 0 — On Error GoTo 0 отключает выбранный режим. Ноль — специальное управляющее значение, не метка и не Boolean-результат. Другие числовые метки и GoTo -1 не поддерживаются.
  • Resume / Resume Next — В обработчике Resume повторяет ошибочную инструкцию, Resume Next продолжает после неё. Нужна сохранённая ошибка выполнения; после перехода её адрес очищается. Метку либо таймаут эти формы в нашем движке не принимают.

Возвращает

On Error и Resume ничего не возвращают. Перехваченная ошибка не превращается в TRUE/FALSE и не исправляет присваивание автоматически. Примеры явно возвращают Integer 5,18,10. Ранее выполненные побочные действия автоматически не откатываются.

Поведение

  • Подготовка разрешает метки после чтения всей процедуры, поэтому работают оба направления. Выполнение сохраняет выбранный режим; при исключении сначала рассматривается структурированный Try, затем On Error.
  • Движок запоминает адрес ошибочной инструкции. Режим метки переходит в обработчик, автоматический Resume Next — за инструкцию. Resume заново вычисляет её выражения и вызовы: сначала устраните причину, учитывая возможное повторение действий.
  • On Error GoTo 0 не стирает сохранённый адрес ошибки: обработчик может отключить себя, исправить данные и выполнить Resume. Отключайте режим перед потенциально ошибочными действиями обработчика, чтобы не войти в него повторно.
  • Ошибки синтаксиса и отмена выполнения здесь не перехватываются. Если команда просто возвращает 0, FALSE или иной статус отказа без исключения, On Error не вызывается — проверяйте результат этой команды.
  • Обычный поток должен обходить обработчик через Return либо явный GoTo. У вызываемой процедуры свой режим. Её неперехваченная ошибка может дойти до вызывающей; Resume тогда повторит всю инструкцию вызова, а не внутреннюю строку. Автоматического предела попыток и задержки нет.
  • Если ошибка вышла из Try после завершения очистки и попала во внешний обработчик On Error GoTo, Resume повторяет весь Try с заголовка. Resume Next продолжает с первой строки после End Try; On Error Resume Next действует так же. Уже выполненные действия при повторе могут повториться: вход обратно в завершённое тело не выполняется.

Примеры

1. Пропустить одно ошибочное присваивание

# values[0] выделяет одну ячейку; индекс 5 недопустим. result начинается с 1. On Error Resume Next пропускает неудачное чтение до присваивания, поэтому result остаётся 1. GoTo 0 отключает режим; result+=4 даёт 5. Main возвращает 5, но не объявляет чтение успешным.
Option Explicit On
Sub Main()
    Dim values[0]
    Var result = 1
    On Error Resume Next
    result = values[5]
    On Error GoTo 0
    result += 4
    Return result
End Sub

Разбор параметров и выполнения:

values[0] выделяет одну ячейку; индекс 5 недопустим. result начинается с 1. On Error Resume Next пропускает неудачное чтение до присваивания, поэтому result остаётся 1. GoTo 0 отключает режим; result+=4 даёт 5. Main возвращает 5, но не объявляет чтение успешным.

2. Исправить и повторить

# ReadCell хранит 8 в ячейке 0, но начинает с index=2. Ошибка чтения переходит к FixIndex. GoTo 0 отключает дальнейшую обработку; handled становится 1, index — 0. Resume повторяет result=values[index] и теперь записывает 8. Return не даёт обычному потоку попасть в обработчик. Main получает 18.
Option Explicit On
Function ReadCell()
    Dim values[0]
    values[0] = 8
    Var index = 2
    Var handled = 0
    Var result = 0
    On Error GoTo FixIndex
    result = values[index]
    Return handled * 10 + result
FixIndex:
    On Error GoTo 0
    handled += 1
    index = 0
    Resume
End Function
Sub Main()
    Return ReadCell()
End Sub

Разбор параметров и выполнения:

ReadCell хранит 8 в ячейке 0, но начинает с index=2. Ошибка чтения переходит к FixIndex. GoTo 0 отключает дальнейшую обработку; handled становится 1, index — 0. Resume повторяет result=values[index] и теперь записывает 8. Return не даёт обычному потоку попасть в обработчик. Main получает 18.

3. Обработчик выше команды

# Начальный GoTo Work обходит Failed при нормальном входе. On Error GoTo Failed подключает эту ранее объявленную метку. Чтение индекса 2 падает до изменения result. Обработчик отключает себя, увеличивает handled и через Resume Next достигает Return. Результат 1*10+0=10. Метки не являются отдельными процедурами.
Option Explicit On
Sub Main()
    Dim values[0]
    Var result = 0
    Var handled = 0
    GoTo Work
Failed:
    On Error GoTo 0
    handled += 1
    Resume Next
Work:
    On Error GoTo Failed
    result = values[2]
    Return handled * 10 + result
End Sub

Разбор параметров и выполнения:

Начальный GoTo Work обходит Failed при нормальном входе. On Error GoTo Failed подключает эту ранее объявленную метку. Чтение индекса 2 падает до изменения result. Обработчик отключает себя, увеличивает handled и через Resume Next достигает Return. Результат 1*10+0=10. Метки не являются отдельными процедурами.


en · ru · uk · fr · de · it · es · zh-tw · ja · ko

Basic