0% found this document useful (0 votes)
52 views

Programming in Lua - 8.3

Uploaded by

Qin Krein
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views

Programming in Lua - 8.3

Uploaded by

Qin Krein
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

This first edition was written for Lua 5.0.

While still largely relevant for later versions, there are


some differences.
The fourth edition
targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

Programming in Lua
Part I. The Language
Chapter 8. Compilation, Execution, and
Errors

8.3 – Errors
Errare humanum est.
Therefore, we must handle errors the best way we can.
Because Lua is an extension language,
frequently embedded in an application,
it cannot simply crash or exit when an error happens.
Instead, whenever an
error occurs,
Lua ends the current chunk
and returns to the application.

Any unexpected condition that Lua encounters raises an error.


Errors occur
when you (that is, your program) try to add
values that are not numbers,
to
call values that are not functions,
to index values that are not tables, and so
on.
(You can modify this behavior using metatables,
as we will see later.)
You
can also explicitly raise an error calling
the error function;
its argument is the
error message.
Usually, that function is the appropriate
way to handle errors
in your code:

print "enter a number:"

n = io.read("*number")

if not n then error("invalid input") end

Such combination of if not ... then error end


is so common that Lua has
a built-in function just for that job,
called assert:

print "enter a number:"

n = assert(io.read("*number"), "invalid input")

The assert function checks whether its first argument is not false
and simply
returns that argument;
if the argument is false (that is, false or nil),
assert
raises an error.
Its second argument, the message, is optional,
so that if you do
not want to say anything in the error message,
you do not have to.
Beware,
however, that assert is a regular function.
As such, Lua always evaluates its
arguments before calling the function.
Therefore, if you have something like

n = io.read()

assert(tonumber(n),

"invalid input: " .. n .. " is not a number")

Lua will always do the concatenation,


even when n is a number.
It may be
wiser to use an explicit test in such cases.

When a function finds an unexpected situation


(an exception), it can assume
two basic behaviors:
It can return an error code (typically nil)
or it can raise
an error, calling the error function.
There are no fixed rules for choosing
between those two options,
but we can provide a general guideline:
An
exception that is easily avoided should raise an error;
otherwise, it should
return an error code.

For instance, let us consider the sin function.


How should it behave when
called on a table?
Suppose it returns an error code.
If we need to check for
errors, we would have to write something like

local res = math.sin(x)

if not res then -- error

...

However, we could as easily check this exception before calling the


function:

if not tonumber(x) then -- error: x is not a number

...

Usually, however, we check neither the argument


nor the result of a call to
sin;
if the argument is not a number,
it means probably something wrong in
our program.
In such situations, to stop the computation and to issue
an error
message is the simplest and
most practical way to handle the exception.

On the other hand, let us consider the io.open function,


which opens a file.
How should it behave when called to read a file that does not exist?
In this
case, there is no simple way to check for the exception
before calling the
function.
In many systems,
the only way of knowing whether a file exists is to
try to open it.
Therefore,
if io.open cannot open a file because of an external
reason
(such as "file does not exist" or "permission denied"),
it returns
nil, plus a string with the error message.
In this way, you have a chance to
handle the situation in
an appropriate way,
for instance by asking the user for
another file name:

local file, msg

repeat

print "enter a file name:"

local name = io.read()

if not name then return end -- no input

file, msg = io.open(name, "r")

if not file then print(msg) end

until file

If you do not want to handle such situations,


but still want to play safe,
you
simply use assert to guard the operation:
file = assert(io.open(name, "r"))

This is a typical Lua idiom:


If io.open fails, assert will raise an error.

file = assert(io.open("no-file", "r"))

--> stdin:1: no-file: No such file or directory

Notice how the error message,


which is the second result from io.open,
goes
as the second argument to assert.

Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved.

You might also like