Message System object reference exception

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
NotVeryProfessional
Posts: 150
Joined: Mon Nov 23, 2020 6:35 am

Message System object reference exception

Post 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
Last edited by NotVeryProfessional on Thu Dec 03, 2020 6:31 am, edited 1 time in total.
NotVeryProfessional
Posts: 150
Joined: Mon Nov 23, 2020 6:35 am

Re: Message System object reference exception

Post 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).
NotVeryProfessional
Posts: 150
Joined: Mon Nov 23, 2020 6:35 am

Re: Message System object reference exception

Post 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.)
NotVeryProfessional
Posts: 150
Joined: Mon Nov 23, 2020 6:35 am

Re: Message System object reference exception

Post 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.
User avatar
Tony Li
Posts: 22049
Joined: Thu Jul 18, 2013 1:27 pm

Re: Message System object reference exception

Post 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.
Post Reply