Page 1 of 1

Message System object reference exception

Posted: Thu Dec 03, 2020 6:03 am
by NotVeryProfessional
Update: Please read 3rd comment first - the problem is not what it seemed to be.


I'm getting this error on two scripts:
Message System exception sending 'SETTLEMENT_SELECTED'/'' to Settlement Details (Mentor.PlaceDetailsUI): Object reference not set to an instance of an object
UnityEngine.Debug:LogError(Object)
PixelCrushers.MessageSystem:SendMessageWithTarget(Object, Object, String, String, Object[]) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Message System/MessageSystem.cs:342)
PixelCrushers.MessageSystem:SendMessage(Object, String, String, Object[]) (at Assets/Plugins/Pixel Crushers/Common/Scripts/Message System/MessageSystem.cs:402)
Mentor.SettlementMarker:OnMouseDown() (at Assets/_Mentor/Scenes/Map/SettlementMarker.cs:62)
UnityEngine.SendMouseEvents:DoSendMouseEvents(Int32) (at /Users/bokken/buildslave/unity/build/Modules/InputLegacy/MouseEvents.cs:161)

The code in question is:

Code: Select all

			MessageSystem.SendMessage(this, "SETTLEMENT_SELECTED", "");

The class that's calling it inherits IMessageHandler. The receiver is set up like this:

Code: Select all

		void OnEnable() {
			MessageSystem.AddListener(this, "SETTLEMENT_SELECTED", string.Empty);
	    }

	    void OnDisable() {
	        MessageSystem.RemoveListener(this);
	    }

		public void OnMessage(MessageArgs messageArgs) {
			switch (messageArgs.message) {
				case "SETTLEMENT_SELECTED":
					UpdateDisplay((SettlementMarker)messageArgs.sender);
					break;
				default:
					Debug.LogError("unknown message received: "+messageArgs.message);
					break;
			}
	    }


I've tried to look into the source but I still can't figure out why it throws this exception. It also does seem to call the target method properly, despite the exception.




Also, side note: debugging sending generates double entries - from line 312 and 334 of MessageSystem.cs

Re: Message System object reference exception

Posted: Thu Dec 03, 2020 6:08 am
by NotVeryProfessional
funny thing: some calls seem to work, some not, despite no difference in how I code listeners and senders (in fact, most code is copy-pasted, with only the message names changed).

Re: Message System object reference exception

Posted: Thu Dec 03, 2020 6:12 am
by NotVeryProfessional
Also, LogWhenReceivingMessages() doesn't seem to work. I get debug messages on the sender, but not on the receiver.

(or on looking at the code it might simply be easy to misunderstand and this could be the cause of the duplicate messages as well - improvement suggestion: Change the message in line 334 slightly, to indicate that this is logging that a message is being received.)

Re: Message System object reference exception

Posted: Thu Dec 03, 2020 6:33 am
by NotVeryProfessional
ok, figured it out:


There were actual errors deeper in my code.

The problem is that the try-catch hides those. The console will log what I showed above, because the OnMessage() call eventually (three methods deeper down) runs on an error, but the backpropagation apparently stops in the message system, so the console log never reveals where the actual error occurred.

That still is a problem, so I'm leaving this open waiting for suggestions on what to do about that.

Re: Message System object reference exception

Posted: Thu Dec 03, 2020 8:39 am
by Tony Li
Hi,

It's important that sending a message should never break the game. That's why the try...catch is there. If there's a possibility that your OnMessage() handler can run into an error, I recommend putting it in its own try...catch. Example:

Code: Select all

public void OnMessage(MessageArgs messageArgs) {
    try
    {
        switch (messageArgs.message) {
            case "SETTLEMENT_SELECTED":
                UpdateDisplay((SettlementMarker)messageArgs.sender);
                break;
            default:
                Debug.LogError("unknown message received: "+messageArgs.message);
                break;
            }
        }
        catch (System.Exception e) // Or use more specific exceptions if it matters.
        {
            Debug.LogException(e);
        }
    }
}
p.s. - The two Debug.Logs are because the message sender and message receiver can both be configured to log them. If the sender and receiver are the same, you'll see two similar Debug.Logs.