This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
ShadowDisruptor's profile picture

Error catching without ending

Started by ShadowDisruptor, 17 September 2014 - 08:04 PM
ShadowDisruptor #1
Posted 17 September 2014 - 10:04 PM
My code (found in the spoiler below) is meant to basically do what find does (Sort peripherals) in a version of computercraft that dosen't have peripheral.find. I simply need to run these functions in ok, err = pcall(). When I do so, they still return the error and end the program. The goal is to have it NOT do that. If someone could work out this error or explain it to me, I'd be very grateful (Also, if you use the latest version of Tekkit main, getting it to work would be even better :)/> ) The error I get is 4: attempt to call nil
Spoiler

--Start of setup
local function isReactor(input)
   local tempReactor = peripheral.wrap(input)
   local checkReactor = tempReactor.getConnected()
   return checkReactor
end
local function whatIs(input)
   local reactor = peripheral.wrap(input)
   local whatIsIt = reactor.isActivelyCooled()
   if whatIsIt then
	  table.insert(activeReactors, input)
   else
	  table.insert(passiveReactors, input)
   end
end

bigReactors = {}
passiveReactors = {}
activeReactors = {}
turbines = {}

--End of setup
--Sorting peripherals
foundPeripherals = peripheral.getNames()
for i=1,#foundPeripherals do
   ok, err = pcall(isReactor(foundPeripherals[i]))
   if ok then
	  table.insert(bigReactors, foundPeripherals[i])
   else
print(foundPeripherals[i].." Is not a reactor!")
   end  
end
foundPeripherals = nil
ok = true
for i=1,#bigReactors do
   ok, err = pcall(whatIs(bigReactors[i]))
   if not ok then
	  table.insert(turbines, bigReactors[i])
   end
end
print("Turbines found: "..#turbines)
print("Active reactors found: "..#activeReactors)
print("Passive reactors found: "..#passiveReactors)
Edited on 17 September 2014 - 08:05 PM
TheOddByte #2
Posted 17 September 2014 - 10:12 PM
I think you're using pcall wrong
For example, you have to put the function first, then the arguments

local ok, err = pcall( term.setTextColor, colors.lime ) -- separate them
So you would have todo this

local ok, err = pcall( isReactor, foundPeripherals[i] )
ShadowDisruptor #3
Posted 17 September 2014 - 10:25 PM
I think you're using pcall wrong
For example, you have to put the function first, then the arguments

local ok, err = pcall( term.setTextColor, colors.lime ) -- separate them
So you would have todo this

local ok, err = pcall( isReactor, foundPeripherals[i] )

isReactor(foundPeripherals) is the function I'm calling. foundPeripherals is the input. When I tried doing what you did with the first example and the line that wasn't working, nothing happened. EDIT: I've got it now, thanks for the help!
Edited on 17 September 2014 - 08:28 PM
TheOddByte #4
Posted 17 September 2014 - 10:35 PM
- Snip -
No problem, I have a suggestion for you, you should use locals

local foo = "bar"
if 1 == 1 then
    local foo = "blah" -- This will be local to the statement, same goes for loops and functions
end
print( foo ) -- will output bar
If your variables isn't local they'll be accessible outside of your program, which would be very bad if you'd use variables to store credentials.
Bomb Bloke #5
Posted 18 September 2014 - 02:18 AM
pcall isn't really the way to go about this… It's more for those circumstances where there will potentially be errors you can't avoid. Here, you can avoid them, by not trying to call functions which don't exist.

Currently, you're trying to call "getConnected()" once for every peripheral attached to your system, regardless as to whether they have that function. There are a couple of ways you can check to see if it's available:

One is to outright ask. In Lua, if you stick a variable on its own into a "for" statement, it'll count as true if it exists, and false if it doesn't. Eg:

if tempReactor.getConnected then    -- If there's an entry in "tempReactor" called "getConnected", then...
  return tempReactor.getConnected() -- ... run it and return the result...
else return false end               -- ... or if there isn't, just return false.

Another way, at least as far as peripherals goes, is to check the type of peripheral you've got. If you use peripheral.getType() on a BigReactor control port it'll return "BigReactors-Reactor", so we can do:

if peripheral.getType(input) == "BigReactors-Reactor" then
  return tempReactor.getConnected()
else return false end