+ Reply to Thread
Results 1 to 6 of 6

Thread: Error handling in coroutines

  1. #1
    Shield of Telara Adelea's Avatar
    Join Date
    Mar 2011
    Posts
    734

    Default Error handling in coroutines

    It seems that lua errors that get thrown in a coroutine get swallowed up and lost.

    Is this intentional? Is there anyway to avoid it?

    In an attempt to work around the Watchdog, I am trying to do the time consuming UI creation inside a coroutine, however, if certain variables arent setup, then the lua fails, but nothing is shown as an error - so it makes trying to work out what is going wrong, pretty difficult !

    Code:
    function mkerror()
    	local x = nil
    	print("Here1")
    	print(string.format("X = %s", x))
    	print("Here2")
    end
    
    mkerror()
    This displays "Here1", then throws an error, as expected:

    bad argument #2 to 'format' (string expected, got nil)

    If we then try:

    Code:
    function mkerror()
    	local x = nil
    	print("Here1")
    	print(string.format("X = %s", x))
    	print("Here2")
    end
    
    coro = coroutine.create(mkerror)
    coroutine.resume(coro)
    This displays Here1, then nothing... The error just disappears.
    http://forums.riftgame.com/image.php?type=sigpic&userid=125779&dateline=13553  38065

  2. #2
    Sword of Telara DoomSprout's Avatar
    Join Date
    Apr 2011
    Posts
    876

    Default

    Using coroutine.resume(), lua will swallow the error and then return false plus the error message to the caller.

    I think you have two choices, catch the error and re-throw it:

    Code:
    function mkerror()
    	local x = nil
    	print("Here1")
    	print(string.format("X = %s", x))
    	print("Here2")
    end
    
    coro = coroutine.create(mkerror)
    local ok, errorMsg = coroutine.resume(coro)
    if not ok then
        error("Error in co-routine coro: " .. errorMsg)
    end
    or use wrap instead of resume: (wrap doesn't return the error, it throws it immediately)

    Code:
    function mkerror()
    	local x = nil
    	print("Here1")
    	print(string.format("X = %s", x))
    	print("Here2")
    end
    
    local coro = coroutine.create(mkerror)
    local coroCaller = coroutine.wrap(mkerror)
    coroCaller()
    Last edited by DoomSprout; 07-06-2012 at 03:15 PM.

    Gadgets: Unit Frames and Other Stuff for RIFT

  3. #3
    Shield of Telara Adelea's Avatar
    Join Date
    Mar 2011
    Posts
    734

    Default

    Ahah! I see, thank you!

    The brief tutorial on coroutines I read didnt mention that lua would swallow up the errors, so I was a bit puzzled there.
    http://forums.riftgame.com/image.php?type=sigpic&userid=125779&dateline=13553  38065

  4. #4
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    Quote Originally Posted by Adelea View Post
    Ahah! I see, thank you!

    The brief tutorial on coroutines I read didnt mention that lua would swallow up the errors, so I was a bit puzzled there.
    But it told you to read the Lua manual if you intend on using coroutines, didn't it?
    Last edited by Imhothar; 07-07-2012 at 07:39 AM.
    Author of the Imhothar's Bags addon.

  5. #5
    Plane Walker Imhothar's Avatar
    Join Date
    Feb 2012
    Posts
    439

    Default

    On a more serious note, the error checking DoomSprout mentioned can be simplified with assert:
    Code:
    function mkerror()
    	local x = nil
    	print("Here1")
    	print(string.format("X = %s", x))
    	print("Here2")
    end
    
    coro = coroutine.create(mkerror)
    assert(coroutine.resume(coro))
    If you need to remove the coroutine from a queue or set a variable to nil and your coroutine.yield has no paramters or whatever you can delay that to the next invokation:
    Code:
    function runJob()
    	if(job) then
    		if(coroutine.status(job) == "dead") then
    			-- Either raised error or finished
    			job = nil
    		else
    			assert(coroutine.resume(job))
    		end
    	end
    end
    Last edited by Imhothar; 07-07-2012 at 09:06 AM.
    Author of the Imhothar's Bags addon.

  6. #6
    Rift Disciple
    Join Date
    Oct 2014
    Posts
    136

    Default

    Thanks guys Love RIFT

    For embedded lua should be so as well:

    if (lua_resume(L, nullptr, nargs) > LUA_YIELD)
    {
    lua_error(L);
    }


    That's funny....couldn't figure why I don't see errors raised by C code ...and google sent me to RIFT ...

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts