Jump to content




Custom Error's Using pcall()


21 replies to this topic

#1 Henness

  • Members
  • 189 posts

Posted 21 January 2014 - 01:15 PM

I'm trying to add an error menu to my gui program so if it runs a program that results in an error then it will print the error in a new menu.

I cant seem to make a custom error message for if the program is being used wrong. I don't really know how to use pcall() can you even return a custom error message back to it?

http://pastebin.com/QpfucDe1

GUI program:
  bError, sError = pcall(shell.run, "program name", "variable")
  if not bError then
	menustate = "error menu"
  else
	menustate = "main menu"
  end

Program ran by GUI program:
   if turtle.getFuelLevel() > 0 then
	return false, "Error, there must be fuel in the turtle!"
   end
also tryed
   if turtle.getFuelLevel() > 0 then
	return "Error, there must be fuel in the turtle!"
   end

Edited by Henness, 21 January 2014 - 01:20 PM.


#2 CometWolf

  • Members
  • 1,283 posts

Posted 21 January 2014 - 02:29 PM

if an error is raised within a pcall, it returns false and the error message. If the function returns without erroring, it returns true aswell as any variables returned. To make your own error messages, you can either use the error function
error("Error message here!")

or assert, which raises an error if the first argument is false
assert(boolean,"Error message here!")
Assert is pretty much error with an if not condition.

http://www.lua.org/pil/8.3.html pcall
http://www.lua.org/pil/8.4.html assert

Edited by CometWolf, 21 January 2014 - 02:30 PM.


#3 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 21 January 2014 - 02:30 PM

Shell.run doesn't return any of the values returned by whatever it ran.

#4 Henness

  • Members
  • 189 posts

Posted 21 January 2014 - 02:56 PM

So would it look like this?
   if turtle.getFuelLevel() > 0 then
	    return assert(false,"Error, there must be fuel in the turtle!")
   end
or
   if turtle.getFuelLevel() > 0 then
	    assert(false,"Error, there must be fuel in the turtle!")
   end


#5 robhol

  • Members
  • 182 posts

Posted 21 January 2014 - 03:02 PM

The return value from assert is also of no particular interest, the entire point is that it errors if the assertion doesn't work out- ie. evaluates to false.

#6 Henness

  • Members
  • 189 posts

Posted 21 January 2014 - 03:46 PM

Okay so this is a basic version of what I have.
But this does not seem to be working, it doesnt print the error.

Main program:
bError, sError = pcall(shell.run, "testprogram", "variable")
if not bError then
   print(sError)
else
   -- continue
end

Test program:
error("This is an Error")


#7 H4X0RZ

  • Members
  • 1,315 posts
  • LocationGermany

Posted 21 January 2014 - 03:53 PM

Remove the 'not' before bError

#8 Henness

  • Members
  • 189 posts

Posted 21 January 2014 - 04:17 PM

That isn't working either and I'm fairly sure it's supposed to have the "not" because if it errors bError returns false.

it just prints false.

#9 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 21 January 2014 - 04:20 PM

Try catching the return values in a table and see if any of the indices contain anything interesting.

#10 Henness

  • Members
  • 189 posts

Posted 21 January 2014 - 04:34 PM

What's the best way to do that, I haven't used lua for a while.

#11 Henness

  • Members
  • 189 posts

Posted 21 January 2014 - 05:20 PM

Scratch that,

only two values were returned

first was true and second was false which doesn't seem to make sense because the first value should be false and the second should be a string.

#12 Henness

  • Members
  • 189 posts

Posted 22 January 2014 - 04:35 AM

I have been thinking about this all day, and just before I was about to go to bed I thought. Maybe the pcall is returning true because the shell.run is completing without errors but the part that is acualy erroring is whats inside the shell.run. Can anyone conferm this is what's happening? And if so can I put a pcall inside the shell.run or is the another way of doing it.

Edited by Henness, 22 January 2014 - 04:40 AM.


#13 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 22 January 2014 - 04:54 AM

That indeed sounds a lot like what Lyqyd was saying above.

Edit: I've not played with them, so I'm not even sure they're available within ComputerCraft, but I suspect you want something along the lines of dofile() or loadfile().

Edited by Bomb Bloke, 22 January 2014 - 04:57 AM.


#14 Henness

  • Members
  • 189 posts

Posted 22 January 2014 - 05:15 PM

 Bomb Bloke, on 22 January 2014 - 04:54 AM, said:

That indeed sounds a lot like what Lyqyd was saying above.

Edit: I've not played with them, so I'm not even sure they're available within ComputerCraft, but I suspect you want something along the lines of dofile() or loadfile().

Thanks Bomb, that works first time I have ever seen dofile and loadfile there isn't much info on them either. I think that the shell.run should be modified to return values :/

#15 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 22 January 2014 - 05:31 PM

dofile and loadfile are available in ComputerCraft. os.run uses loadfile to run programs.

#16 Henness

  • Members
  • 189 posts

Posted 22 January 2014 - 07:32 PM

os.run() seems work for running the program but every error is returned as attempt to call boolean. Because its not storing a string in sError. (I think)

bError, sError = pcall(os.run({}, "advancedorefinder", "orefinder.save"))

Loadfile() seems to work too but if I use it then The program that it runs cant use shell.getRunningProgram() :(

Edited by Henness, 22 January 2014 - 07:39 PM.


#17 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 22 January 2014 - 07:42 PM

Of course it can, you just have to set the environment correctly for it. Read through shell and bios.lua and watch for how it sets the environment for the programs it runs.

#18 Henness

  • Members
  • 189 posts

Posted 22 January 2014 - 09:16 PM

Im not quite sure how I'm supposed to set up the environment. Im looking in shell and from what I can see shell.getRunningProgram() isn't going to work if I run a program with loadfile().

Because when you run a program with shell.run it adds the program to a new spot at the end of a table with tProgramStack[#tProgramStack + 1] = sPath then when you call shell.getRunningProgram() it just returns the last variable in the table

Unless your talking about os.run()

Edited by Henness, 22 January 2014 - 09:56 PM.


#19 CometWolf

  • Members
  • 1,283 posts

Posted 23 January 2014 - 12:15 AM

Why do you need shell.getRunningProgram? Don't you already know the file path prior to using os.run on it anyways?

#20 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 23 January 2014 - 12:59 AM

You didn't look very hard in shell.

Lines 11-13:

local tEnv = {
    ["shell"] = shell,
}

Line 32 of shell, in the shell.run function:

local result = os.run( tEnv, sPath, ... )

And lines 364-367 of bios.lua:

setfenv( fnFile, tEnv )
local ok, err = pcall( function()
    fnFile( unpack( tArgs ) )
end )

You can glance through the files for more context on what the variable names are, but tEnv happens to be consistently named, so that part should be pretty easy to figure out.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users