dan200 / ComputerCraft

Programmable Computers for Minecraft
Other
980 stars 198 forks source link

ArrayIndexOutOfBoundsException #425

Closed Janrupf closed 7 years ago

Janrupf commented 7 years ago
--init
os.loadAPI("controllerDir/json")

--Monitor
mon = peripheral.wrap("top")

--Shortcuts
r = "right"
l = "left"

--other vars
tracks = {}
before = 1

--functions
function arg(arg, _type)

  if type(arg) ~= _type then
    term.setTextColor(colors.red)
    error("Bad argument: Expected ".._type.." but got "..type(arg).."!")
  end
end

function trainOnTrack(track)
  arg(track, "number")
  return rs.testBundledInput("right", track) 
end

function placeholder() 

  w,h = term.getSize()

  for i=1, w, 1 do
    write("-")
  end

end

function regTrack(color)

  arg(color, "number")
  table.insert(tracks, color)

end

function openRednet()

  for _,side in ipairs(rs.getSides()) do
    if peripheral.isPresent(side) and peripheral.getType(side) == "modem" then
      rednet.open(side)
      return side
    end
  end
  error("No modem connected!")
end

try = 0

function sendTrain()

  r = math.random(1, #tracks)
  color = tracks[r]
  train = trainOnTrack(colors.red)

  if not train then
    try = try +1
    if try == 14 then
      print("Found 14 times no train, sleeping 2 sec")
      sleep(2)
    end

    if try == 20 then
      print("Found 20 times no train, giving up...")
    else
      sendTrain()
    end
  else
    rs.setBundledOutput("left", color)
    sleep(2)
    rs.setBundledOutput("left", 0)
    try = 0
    print("Train send!")
  end
end

--Code
print("Starting controller...")
placeholder()
print("MC-V:".. _MC_VERSION)
print("CC-V:".. _CC_VERSION)
print("LuaJ-V:".. _LUAJ_VERSION)
placeholder()
openRednet()
rednet.host("json","train.base.red")

regTrack(colors.blue)

function handle()
  id,msgraw = rednet.receive("json")
  print("Recived")
  term.setTextColor(colors.orange)
  print(msgraw)
  term.setTextColor(colors.white)
  write("from ")
  term.setTextColor(colors.blue)
  print(id)
  term.setTextColor(colors.white)
  --#META_SETUP#--
  msg = {}
  msg_meta = {}
  setmetatable(msg, msg_meta)
  msg_meta.__index = 
  function(table, key)
    print("Invalid message recived! (Value for " .. key .. "is nil!")
    placeholder()
    handle()
  end
  --#META_SETUP#--    

  msg = json.decode(msgraw)
  if msg == nil then
    print("Invalid message recived! (No JSON)")
    placeholder()
    handle()
  end

  if msg.command == "send" then
    print("Remote send request recived!")
    sendTrain()
  end

  placeholder()
end

while true do 
  handle()
end

So, hello, the code above will result in an ArrayIndexOutOfBoundsExecption after the second fail... Im not getting any stacktrace in console (running on a server).

Here is an screenshot: 2017-08-22

MC-Version: 1.7.10
CC-
Version: 1.75

If Im doing something wrong then tell me ;)

Lupus590 commented 7 years ago

This is likely a bug in your own code. In future, you would be better off posting on the forums.

As for the cause of the issue, your function calls itself:

  if msg == nil then
    print("Invalid message recived! (No JSON)")
    placeholder()
    handle()
  end

Every time you call a function, a new "instance" of that function goes on the end of the "function stack" (really a Java array with LuaJ, as is used by ComputerCraft). Every time a function completes, it's removed from the stack and execution continues from the point where the previous function instance left off. - [source](http://www.computercraft.info/forums2/index.php?/topic/28876-javalangarrayindexoutofboundsexception/page__view__findpost__p__268721]

handle sometimes calls itself and sometimes (always?) never returns, each time this means that the function stack (stored in a java array) gets bigger. Eventually this overflows causing the error message you received,

SquidDev commented 7 years ago

This generally means you're getting a stack overflow - probably as sendTrain calls itself. I think this is as try is never reset on a failure, so is 21 when called the second time.

Janrupf commented 7 years ago

Maybe I should sleep a while. I trying it I often let functions call itself, but i9 never tried it without sleeping

Janrupf commented 7 years ago

adding a sleep block fixed the issuise, maybe cc should output the stacktrace to the console (or is there a debug mode?)

BombBloke commented 7 years ago

Although the crash is indeed due to problems in the script, how tricky would it be to have ComputerCraft produce a more descriptive error? "Too many functions in stack" or somesuch?

SquidDev commented 7 years ago

163 will error with "stack overflow" instead, which is what PUC Lua does.

dan200 commented 7 years ago

This is undoubtably a bug in your program, not cc

Lupus590 commented 7 years ago

@dan200 the topic of the issue changed to having CC give a clearer error for stack overflow. Thoughts?