Lua - обработка ошибок

Необходимость обработки ошибок

Обработка ошибок очень важна, поскольку в реальных операциях часто требуются сложные операции, в том числе операции с файлами, транзакции с базой данных и вызовы веб-служб.

В любом программировании всегда есть требование обработки ошибок. Ошибки могут быть двух типов, включая:

  • Синтаксические ошибки
  • Ошибки времени выполнения

Ошибки синтаксиса

Синтаксические ошибки возникают из-за неправильного использования различных компонентов программы, таких как операторы и выражения. Ниже показан простой пример синтаксической ошибки.

a == 2

Как вы знаете, существует разница между использованием одинарного «равно» и двойного «равно». Использование одного вместо другого может привести к ошибке. Одно «равно» относится к присваиванию, а двойное «равно» относится к сравнению. Точно так же у нас есть выражения и функции, имеющие предопределенные способы реализации.

Другой пример синтаксической ошибки показан ниже -

for a= 1,10
   print(a)
end

Когда мы запустим вышеуказанную программу, мы получим следующий результат -

lua: test2.lua:2: 'do' expected near 'print'

Синтаксические ошибки намного легче обрабатывать, чем ошибки времени выполнения, поскольку интерпретатор Lua обнаруживает ошибку более четко, чем в случае ошибки времени выполнения. Из приведенной выше ошибки мы можем легко узнать, что в соответствии со структурой Lua требуется добавление оператора do перед оператором печати.

Ошибки времени выполнения

В случае ошибок времени выполнения программа выполняется успешно, но это может привести к ошибкам времени выполнения из-за ошибок ввода или неправильно обработанных функций. Ниже показан простой пример, показывающий ошибку времени выполнения.

function add(a,b)
   return a+b
end

add(10)

Когда мы построим программу, она будет успешно построена и запущена. После запуска показывает ошибку времени выполнения.

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
	test2.lua:2: in function 'add'
	test2.lua:5: in main chunk
	[C]: ?

Это ошибка времени выполнения, которая произошла из-за не передачи двух переменных. Вb ожидаемый параметр, здесь он равен нулю и выдает ошибку.

Функции утверждения и ошибки

Для обработки ошибок мы часто используем две функции: assert и error. Ниже показан простой пример.

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   return a+b
end

add(10)

Когда мы запустим указанную выше программу, мы получим следующий вывод ошибки.

lua: test2.lua:3: b is not a number
stack traceback:
	[C]: in function 'assert'
	test2.lua:3: in function 'add'
	test2.lua:6: in main chunk
	[C]: ?

В error (message [, level])завершает вызов последней защищенной функции и возвращает сообщение как сообщение об ошибке. Ошибка этой функции никогда не возвращается. Обычно ошибка добавляет некоторую информацию о позиции ошибки в начале сообщения. Аргумент уровня указывает, как получить позицию ошибки. При уровне 1 (по умолчанию) позиция ошибки - это место, где была вызвана функция ошибки. Уровень 2 указывает на ошибку, где была вызвана функция, вызвавшая ошибку; и так далее. Передача уровня 0 позволяет избежать добавления в сообщение информации о местоположении ошибки.

pcall и xpcall

В программировании на Lua, чтобы избежать появления этих ошибок и ошибок обработки, нам необходимо использовать функции pcall или xpcall.

В pcall (f, arg1, ...)функция вызывает запрошенную функцию в защищенном режиме. Если в функции f возникает какая-то ошибка, она не вызывает ошибки. Он просто возвращает статус ошибки. Ниже показан простой пример использования pcall.

function myfunction ()
   n = n/nil
end

if pcall(myfunction) then
   print("Success")
else
	print("Failure")
end

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

Failure

В xpcall (f, err)функция вызывает запрошенную функцию, а также устанавливает обработчик ошибок. Любая ошибка внутри f не распространяется; вместо этого xpcall перехватывает ошибку, вызывает функцию err с исходным объектом ошибки и возвращает код состояния.

Ниже показан простой пример для xpcall.

function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
   print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

Когда мы запустим вышеуказанную программу, мы получим следующий результат.

ERROR:	test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false

Как программист, очень важно заботиться о правильной обработке ошибок в программах, которые вы пишете. Использование обработки ошибок может гарантировать обработку непредвиденных условий за граничными условиями, не мешая пользователю программы.