When I msg.post to non-existent game objects or components using a protected call (e.g. local ok, _ = pcall(msg.post, "default:/bad#url, "some_message")
), no error is caught (pcall returns true) even though I see ERROR:GAMEOBJECT
console output complaining that the URL could not be found. However, posting to a non-existent socket throws an error pcall can catch (pcall returns false). Is this how it’s supposed to work, or am I doing something wrong?
I’m a Defold novice working my way through the “What next?” section of the ColorSlide tutorial and, in playing with the case where the player completes the last level and there is no “next” one (exercise 4), came across a suggestion to use pcall
to detect when the msg.post fails (because it’s directed at the non-existent proxy for level 5): [SOLVED] Checking collection exists before proxy loading - #2 by Mathias_Westerdahl I also saw a (much older) post suggesting that a msg.post to a bad URL should throw an error that’s caught in protected mode: Defold doesn't show any error and stop execution of the сoroutine if you wrongly send message from module msg.post (SOLVED) - #10 by britzl
To reproduce:
- Check out the tutorial-done branch of ColorSlide (GitHub - defold/tutorial-colorslide at tutorial-done)
- In loader.script’s
on_message
, wrap themsg.post(proxy, "load")
in a protected call like so:
function on_message(self, message_id, message, sender)
if message_id == hash("load_level") then
self.current_level = message.level
local proxy = "#proxy_level_" .. self.current_level
-- msg.post(proxy, "load")
local ok, _ = pcall(msg.post, proxy, "load")
if ok then
print("Pcall msg.post to " .. proxy .. ": OK.")
else
print("Pcall msg.post to " .. proxy .. ": NOT OK.")
end
- Run the game and select level 4. The console output reads:
DEBUG:SCRIPT: Pcall msg.post to #proxy_level_4: OK.
- Clear level 4 (or cheat by binding an input to trigger the “Well done!” popover, like I did
), then click the “Next >” button. The console output reads:
DEBUG:SCRIPT: Pcall msg.post to #proxy_level_5: OK.
ERROR:GAMEOBJECT: Component '/loader#proxy_level_5' could not be found when dispatching message 'load' sent from default:/loader#loader
Given the two forum replies above, I thought that ok
would be false since the message dispatch failed, but instead it’s true.
Experimentation shows that posting to a nonexistent object within an existing socket does the same…
DEBUG:SCRIPT: Pcall msg.post to default:/nonexistentobject#nonexistentcomponent: OK.
ERROR:GAMEOBJECT: Instance '/nonexistentobject' could not be found when dispatching message 'load' sent from default:/loader#loader
…but posting to a nonexistent socket does throw an error the pcall can catch:
DEBUG:SCRIPT: Pcall msg.post to nonexistentsocket:/nonexistentobject#nonexistentcomponent: NOT OK.
Is this how it’s supposed to work? Apologies if this is addressed in the docs or somewhere else on the forum – I looked but couldn’t find anything definitive, and I’m afraid pulling an answer out of the engine’s source is presently beyond me.
(All above done on Defold 1.10.0 stable on macOS x86_64, installed via the .dmg from GitHub’s releases page.)