summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-11-20 17:32:37 +0000
committerRichard W.M. Jones <rjones@redhat.com>2012-11-20 17:32:37 +0000
commit1f984509952865632f434b4349f679a2e4a42935 (patch)
treee257801925a730b357836fd00795effa63e55d76
parent4749bff379862205dfa6c6ff94984711894c9eb0 (diff)
downloadlibguestfs-1f984509952865632f434b4349f679a2e4a42935.tar.gz
libguestfs-1f984509952865632f434b4349f679a2e4a42935.tar.xz
libguestfs-1f984509952865632f434b4349f679a2e4a42935.zip
lua: Attach __tostring functions exceptions.
This includes a test.
-rw-r--r--generator/lua.ml29
-rw-r--r--lua/Makefile.am8
-rw-r--r--lua/examples/guestfs-lua.pod8
-rwxr-xr-xlua/tests/900-errors.lua37
4 files changed, 77 insertions, 5 deletions
diff --git a/generator/lua.ml b/generator/lua.ml
index ddf3200f..c7ee925a 100644
--- a/generator/lua.ml
+++ b/generator/lua.ml
@@ -199,6 +199,28 @@ lua_guestfs_close (lua_State *L)
return 0;
}
+/* __tostring function attached to all exceptions. */
+static int
+error__tostring (lua_State *L)
+{
+ int code;
+ const char *msg;
+
+ lua_pushliteral (L, \"code\");
+ lua_gettable (L, 1);
+ code = luaL_checkint (L, -1);
+ lua_pushliteral (L, \"msg\");
+ lua_gettable (L, 1);
+ msg = luaL_checkstring (L, -1);
+
+ if (code)
+ lua_pushfstring (L, \"%%s: %%s\", msg, strerror (code));
+ else
+ lua_pushstring (L, msg);
+
+ return 1;
+}
+
/* Return the last error in the handle. */
static int
last_error (lua_State *L, guestfs_h *g)
@@ -214,6 +236,13 @@ last_error (lua_State *L, guestfs_h *g)
lua_pushinteger (L, guestfs_last_errno (g));
lua_settable (L, -3);
+ lua_newtable (L);
+ lua_pushliteral (L, \"__tostring\");
+ lua_pushcfunction (L, error__tostring);
+ lua_settable (L, -3);
+
+ lua_setmetatable (L, -2);
+
/* Raise an exception with the error object. */
return lua_error (L);
}
diff --git a/lua/Makefile.am b/lua/Makefile.am
index 8cc5930d..11ebea71 100644
--- a/lua/Makefile.am
+++ b/lua/Makefile.am
@@ -50,7 +50,7 @@ guestfs.so: libluaguestfs.la
ln -sf .libs/libluaguestfs.so $@
# Tests.
-TESTS_ENVIRONMENT = $(top_builddir)/run --test
+TESTS_ENVIRONMENT = LC_ALL=C $(top_builddir)/run --test
TESTS = \
run-bindtests \
tests/010-load.lua \
@@ -60,7 +60,8 @@ TESTS = \
tests/027-create-multiple.lua \
tests/030-config.lua \
tests/070-optargs.lua \
- tests/400-events.lua
+ tests/400-events.lua \
+ tests/900-errors.lua
if ENABLE_APPLIANCE
TESTS += \
@@ -80,7 +81,8 @@ EXTRA_DIST += \
tests/060-readdir.lua \
tests/070-optargs.lua \
tests/400-events.lua \
- tests/400-progress.lua
+ tests/400-progress.lua \
+ tests/900-errors.lua
# Custom install rule.
install-data-hook:
diff --git a/lua/examples/guestfs-lua.pod b/lua/examples/guestfs-lua.pod
index 193a9a97..4c72899b 100644
--- a/lua/examples/guestfs-lua.pod
+++ b/lua/examples/guestfs-lua.pod
@@ -90,8 +90,12 @@ The C<errno> (corresponding to L<guestfs(3)/guestfs_last_errno>).
=back
-Note that some errors can also be thrown as plain strings. You
-need to check the type.
+These objects also have C<__tostring> functions attached to them
+so you can use C<tostring> (or implicit conversion) to convert them
+into printable strings.
+
+Note that the library also throws some errors as plain strings. You
+may need to check the type.
=head2 EVENTS
diff --git a/lua/tests/900-errors.lua b/lua/tests/900-errors.lua
new file mode 100755
index 00000000..c560f7f4
--- /dev/null
+++ b/lua/tests/900-errors.lua
@@ -0,0 +1,37 @@
+#!/usr/bin/lua
+-- libguestfs Lua bindings -*- lua -*-
+-- Copyright (C) 2012 Red Hat Inc.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+local G = require "guestfs"
+
+local g = G.create ()
+
+code, err = pcall (function (fn) g:add_drive (fn) end, "/NOTSUCHFILE")
+assert (not code)
+
+-- The default __tostring function will convert the error to either:
+--
+-- "%s", msg
+-- or:
+-- "%s: %s", msg, strerror (err)
+--
+-- We are expecting the second case here, but since the libguestfs
+-- code calls perrorf, the string version of ENOENT is already
+-- included in 'msg' and so appears twice here.
+local str = tostring (err)
+assert (str == "/NOTSUCHFILE: No such file or directory: No such file or directory",
+ string.format ("unexpected error string: %s", str))