Defold doesn't show any error and stop execution of the сoroutine if you wrongly send message from module msg.post (SOLVED)

In case if you have following code

method1()
msg.post("SOME_WRONG_URL_HERE","message")
method2()

Defold doesn’t show any error on msg.post and more over stop execution of next methods. so method2() won’t be fired.

Will be good to see some errors here (after wrong msg.post) so it will be easy to debug.

my use case is following:
I’m trying to reuse my old game world collection at the new place (another collection) with another objects.
My original collection send bunch of messages to the gui (update colors, score, etc…) and at new place I don’t have this gui object and i don’t want to show any game related stuff (score, progress etc.) i just want to “play” some stored user input actions and replay the game without any interaction.

thanks.

There should definitely be an error:

function init(self)
	msg.post("WRONG", "message")
end

results in:

ERROR:GAMEOBJECT: Instance '/WRONG' could not be found when dispatching message 'message' sent from main:/main#script
1 Like

thanks @sicher I’ll try to isolate and reproduce this bug on clean environment. I don’t know why on my sie I didn’t see the error for some msg.post usages. Tried to call in init and everything was ok.

If you manage to repro this please send it over. It should not matter where you send messages, it should work the same.

I just reproduced the bug, it relates to coroutines and modules.

So i have these 2 files

/main/module.lua

local M = {}

function M.send()
	msg.post("default:/test#here", "message")
end

return M

/main/test.script

local mod = require("main.module")

function init(self)
    self.init_c = coroutine.create(init_coroutine)
    coroutine.resume(self.init_c)
end


function init_coroutine(self)
	print("1")	
	mod.send()
	print("2")	
end


function update(self, dt)
	coroutine.resume(self.init_c, self)
end

and this is output

INFO:ENGINE: Defold Engine 1.2.92 (619820e)
INFO:ENGINE: Loading data from: http://192.168.144.20:8080/build/default
INFO:ENGINE: Initialised sound device 'default'

DEBUG:SCRIPT: 1

and if i comment msg.post in the M.send() function of the module I have this

DEBUG:SCRIPT: 1
DEBUG:SCRIPT: 2

Lua coroutines are run in protected mode. This means that any error inside the coroutine will be caught and returned as the result of coroutine.resume(). You need to manually check the return value of coroutine.resume() for any errors while resuming the coroutine.

5 Likes

so how to write the code which will be easy to debug? just avoid to use coroutines and do the same in update cycle with several status checks?


function init(self)
    self.init_c = coroutine.create(init_coroutine)
    coroutine.resume(self.init_c)
end


function init_coroutine(self)
	print("1")	
	msg.post("default:/test#here", "message")
	print("2")	
end


function update(self, dt)
	local errorfree, message = coroutine.resume(self.init_c, self)
	print("errorfree="..tostring(errorfree).."   message:"..message)
end

here is updated version. without modules because as you said problem in coroutines.
and here is output

INFO:ENGINE: Defold Engine 1.2.92 (619820e)
INFO:ENGINE: Loading data from: build/default
INFO:ENGINE: Initialised sound device 'default'

DEBUG:SCRIPT: 1
INFO:DLIB: SSDP: Started on address 192.168.144.18
DEBUG:SCRIPT: errorfree=false   message:cannot resume dead coroutine
DEBUG:SCRIPT: errorfree=false   message:cannot resume dead coroutine
.......
DEBUG:SCRIPT: errorfree=false   message:cannot resume dead coroutine
INFO:DLIB: SSDP: Done on address 192.168.144.18

and “dead coroutine” is exactly the same message as the one returned when coroutine ends. this output from the code where i don’t call msg.post

DEBUG:SCRIPT: 1
DEBUG:SCRIPT: 2
INFO:DLIB: SSDP: Started on address 192.168.144.18
DEBUG:SCRIPT: errorfree=false   message:cannot resume dead coroutine
...

I’m not sure what’s going wrong for you. I need to see more code and I need to better understand what it is you are trying to do.

Also, I just noticed that in your initial code you declared init_coroutine() as a global function (ie without local keyword). Please try to make a habit out of declaring functions and variables as local. Bad things might happen otherwise.

The problem is that i tried to reuse existing code. and had some issues with proxies so some msg.post stop work for me. and when msg.post was inside coroutine. coroutine just stop working without any message. and sims like it’s not possible to catch this kind of errors.

Good point about local variables. I forget to add local modificator quite often because I’m new to lua. definitely i need to avoid using vars in global context.

Just to be 100% clear I’ll repeat what I wrote earlier: coroutines run in protected mode. Any error inside the coroutine will be caught and returned from the call to coroutine.resume(). Like this:

local co = coroutine.create(function()
	print("before")
	msg.post("this:/is#broken", "foobar")    -- this will not work and the coroutine will catch the error and return it to the call to coroutine.resume()
	print("after")
end)
local ok, err = coroutine.resume(co)
if not ok then
	print(err)  -- the error message generated by the broken msg.post() will be output here
end
5 Likes

@britzl thanks a lot,
now i checked my code more precisely and found that i didn’t use error check on resume after coroutine creation in the init(self) method. and this is why i didn’t see any errors in the update(self,dt).

Sorry for taking your time. I found that everything works as you explained.

1 Like