Catch the LuaSQL error to the xpcall error handler function - lua

How can I get the error output from the LuaSQL driver as an argument to the xpcall error function as assert does?
For example, by running the following code:
local conn = assert (env:connect("demo_database",config.db.username,config.db.password,config.db.host))
I'm getting the following error:
LuaSQL: error connecting to database. MySQL: Access denied for user 'user_1'#'host1' (using password: YES)
But when I'm running the following code:
local function myerrorhandler( err )
local file = assert( io.open( "/tmp/testout.txt", "w" ) )
file:write( err.." - error\n" )
file:close()
end
local conn = xpcall (env:connect("demo_database",config.db.username,config.db.password,config.db.host), myerrorhandler)
The error I'm getting in the log file is: attempt to call a nil value - error

xpcall expects the first argument to be a function, which it will call and catch errors from. You are basically doing xpcall(func(), handler), i.e. calling func instead of just passing it to xpcall, similar to how pcall expects a function as first argument.
You basically want to wrap your code in a function:
local conn = xpcall(function()
return env:connect("demo_database", config.db.username, config.db.password, config.db.host)
end, myerrorhandler)

Related

Is it possible to change the output of Lua error messages?

I managed to change the output of error messages by modifying the dbg_printf method. However, that method doesn't handle the following error messages:
lua: ?:0: attempt to call global 'log' (a nil value)
Which method(s) handle these types of errors?
The error message is from the file ldebug.c in the function luaG_typeerror. But i guess you are using an older Lua Version because my message is a bit different:
attempt to call a nil value (global 'log')
You sould try to prevent the error if you can:
if type(log) == "function" then
log()
end
or as #lhf said use pcall:
if pcall(log) then
-- no errors while running 'log'
...
else
-- 'log' raised an error: take appropriate actions
...
end
It should be simpler than digging into the C api.
like #lhf says:
if pcal(risky) then
print("this works")
else
print("phooey!")
end
alternatively you can stop the program and get your error message like this:
if pcal(risky) then
print("this works")
else
error("your error message here")
end

How to return a function value from pcall() in lua

My code (psuedo)
function foo(cmd)
return load(cmd) --Note that this could cause an error, should 'cmd' be an invalid command
end
function moo()
return "moo"
end
function yoo(something)
something.do()
end
cmd = io.read() --Note that a syntax error will call an error in load. Therefore, I use pcall()
local result, error = pcall(cmd)
print(result)
This code looks okay, and works, but my problem is if I type in moo() then result will only show whether or not the command was executed without an error (If the command calls an error, error will have its value).
On another note, if I want to call yoo(), I won't get a return value from it, so I want pcall()'s true / false (or any alternate means other than pcall())
Is there an alternate way to call moo(), get a return value, and also be able to catch any errors?
NOTE: I couldn't find any try catch equivalent other then pcall / xpcall.
A bit outdated but still without proper answer...
What you are looking for is a combination of both load() and pcall()
Use load()to compile the entered string cmd into something that can be executed (function).
Use pcall() to execute the function returned by load()
Both functions can return error messages. Get syntax error description from load() and runtime error description from pcall()
function moo()
return "moo"
end
function yoo(something)
something.do_something()
end
cmd = io.read()
-- we got some command in the form of a string
-- to be able to execute it, we have to compile (load) it first
local cmd_fn, err = load("return "..cmd);
if not cmd_fn then
-- there was a syntax error
print("Syntax error: "..err);
else
-- we have now compiled cmd in the form of function cmd_fn(), so we can try to execute it
local ok, result_or_error = pcall(cmd_fn)
if ok then
-- the code was executed successfully, print the returned value
print("Result: "..tostring(result_or_error));
else
-- runtime error, print error description
print("Run error: "..result_or_error)
end
end

attempt to call method 'random' (a nil value) in Lua

Below is my code
require 'dpnn'
require 'cunn'
local deviceNumber = tonumber(os.getenv("CUDA_CARD_NR"))
cutorch.setDevice(deviceNumber)
local module = nn.Sequential():cuda()
module:add(nn.Linear(2,1):cuda())
module:add(nn.Sigmoid():cuda())
criterion = nn.BCECriterion():cuda() -- Binary Cross Entorpy Criteria
local targets = torch.CudaTensor(10):random(0,1)
local inputs = torch.CudaTensor(10,2):uniform(-1,1)
function trainEpoch(module,criterion,inputs,targets)
for i=1,inputs:size(1) do
local idx = math.random(1,inputs:size(1))
local input, target = inputs[idx], targets:narrow(1,idx,1)
-- forward
local output= module:forward(input)
local loss= criterion:forward(output,target)
-- backward
local gradOutput = criterion:backward(output,target)
module:zeroGradParameters()
local gradInput = module:backward(input,gradOutput)
--update
module:updateGradParameters(0.9) -- momentum
module:updateParameters(0.1) -- W = W -0.1*dL/dW
end
end
for i=1,100 do
trainEpoch(module,criterion,inputs,targets)
end
I am running above using the following command
CUDA_CARD_NR=1 luajit feedforwad.lua
It gives the following error
luajit: feedforwad.lua:13: attempt to call method 'random' (a nil value)
stack traceback:
feedforwad.lua:13: in main chunk
[C]: at 0x004064f0
I know that there is some error in the line
local targets = torch.CudaTensor(10):random(0,1)
But I am not able to figure out.
luajit: feedforwad.lua:13: attempt to call method 'random' (a nil
value)
Is not "some error" and you should not have problems to figure out what is wrong because the error message tells you exactly what is wrong.
You tried to call the a method named random which happens to be a nil value.
This means that there is no function with that name and therefor you can't call it.
According to the reference documentation (which you should have checked befor coming here) the function is actually named rand

Use assert with pcall in Lua

Depending if it errors are raised or not, pcall(function) may return:
Success: true and the return value[s] of the function.
Failure: false and the error.
In my case I'm calling a function to return a table, so in case of no errors I will get my data from the second return value, and in case of error I will print manage the error.
How can I do it with assert?
At first I wrote this:
local ret, data = pcall(the_function)
assert(ret, "Error: "..data)
-- use data from here on.
The problem is that the assert message is evaluated even in case of success, so when the call succeeds Lua complains about concatenating a string with a table.
This problem is due to the fact that I want to use assert and cite the error, but avoiding using something like if not ret then assert(false, "...") end.
Try this:
local ret, data = assert(pcall(the_function))
If you don't need to alter the error message from pcall lhf's suggestion is best.
Otherwise a solution is:
local ret, data = pcall( the_function )
assert( ret, type( data ) == 'string' and "Error: " .. data )
or this one, which is a cleaner approach:
local ret, data = pcall( the_function )
if not ret then error( "Error: " .. data ) end
this latter avoids completely to evaluate the error message expression if pcall doesn't give an error.

How to run multiple lua scripts through a single lua script even if one script fails

dofile("x/y/m.lua")
dofile("x/y/p.lua")
if m.lua fails due to some issue , p.lua will not run at all, please give me some resolution that i can run both files even if the first one fails and have logs for both
Try
function dofile(name)
local f,err=loadfile(name)
if f==nil then print(err) end
local ok,err=pcall(f)
if not ok then print(err) end
end
Use pcall to catch Lua errors, possibly like this:
local success, result = pcall(dofile, "foo.lua")
If success is false, the function failed and the error message will be in result. If success is true, the return values of dofile will be in result. You can add additional result variables. For example:
local success, result1, result2, result3 = pcall(dofile, "foo.lua")

Resources