D365 Infolog Messages

Share this:

Developers add code to show D365 infolog messages to help the user understand what occurred during a process. Oftentimes, a D365 user will see exactly what data they are interacting with on the form they have open. However, other times, a user will perform an action, such as saving a record or pushing a button, that will cause the system to do many unseen things. In those scenarios, D365 infolog messages added to the code are very helpful in informing the user what happened.

Understanding Infolog messages

To explain, for those unfamiliar with the term ‘infolog‘, this refers to the primary messaging system within Microsoft Dynamics 365 for Finance and Operations. Additionally, an ‘infolog message‘ is any message shown in the infolog.

Correspondingly, one of the first things a developer learns when working with a new programming language is how to ‘print‘ messages to the screen. The ability to print a message helps a developer confirm the code is doing what it is supposed to do.

For example, the method ‘print()’ is used in the programming language Python.

print("Hello World")

Next, in the programming language C#, the method Console.WriteLine() is used.

Console.WriteLine("Hello World!");

Most of the time, these messages are for the end user to see. However, sometimes the messages are really just for a developer to see in case there is an issue. For example, in JavaScript, a developer can use console.log() to display a message only to the developer tool console.

console.log("Hello world!");

Finally, in the programming language X++, D365 infolog messages are shown to the screen using one of three methods: Info(), Warning(), or Error().

info("Hello world!");
warning("The system encountered something that was concerning, but was able to proceed anyway.");
error("An error occurred, and the process was unable to complete.");

Technically, there is a ‘print’ statement. However, the print statement will only output to the Visual Studio Output window when debugging using Visual Studio in Microsoft Dynamics 365 for Finance and Operations. Therefore, it is best practice to NOT use it and instead use one of the other methods that will display on the browser.

print("This is an example of a print message");

Why Show A Message?

While initially, a developer might add many D365 infolog messages to help them while testing their code, they should leave in some messages to help users understand what happened.

For example, when the user asks the system to process several records, such as invoicing multiple sales orders, one sales order might fail to invoice, but the others may succeed. How does the user know which sales order failed?

Notably, they could refresh the form and look at the status of the sales orders to see which one is not in the status of ‘invoiced.’ However, this could be time-consuming and hard to do if there are many records to look through. Instead, a developer can add D365 infolog messages telling the user which sales order failed to invoice.

Types Of Infolog Messages

There are three different methods in X++ that all show D365 infolog messages: Info, Warning, and Error. However, each should be used for different purposes.

First, the Info method shows the message with a blue background. Additionally, by best practice, it should be used to display messages that are simply informational. For example, the message could explain that a journal was posted.

Info("The journal was successfully posted");

Second, the Warning method shows the message with a yellow background. To follow best practices, developers should only use this method when sharing information to caution the user. However, receiving a warning message typically means the process was still successful. For example, it could warn that a combination of values is not valid and needs to be changed before the system can save the record.

Warning("An item cannot be saved with that configuration");  

For example, open Visual Studio, then go to View>Application Explorer. Next, type ‘InvenTable’ into the search bar and press enter. Then, locate Data Model>Tables>InventTable, right-click on InventTable and select ‘view code‘.

In the open code editor, look at the ‘validatePackingGrossWeightVolume‘ method. Note that the system displays a message saying that if the item is saved with the current values, some functionality may not work as expected.

Lastly, the Error method shows the message with a red background. As a best practice, developers should only use this method when indicating that something went wrong and the process was not complete. For example, the message could explain that an error occurred and the journal was not posted.

throw Error("An error occurred during journal posting.");

Technically, any of the three methods could be used by a developer to display a message in any situation. However, unless they are used in the situations described, they will confuse the users who are expecting them to work this way.

Try It Out

In order to test this code, create a D365 project. Then, create a runnable class (job). Finally, enter or copy and paste the code into the main method.

Dynamic Messages

In the examples shown so far, only static text has been displayed. Importantly, messages that change based on variables in code can be shown to the user.

For example, previously we discussed the need to show which sales order failed to invoice. In that situation, write code to pass the sales order ID to the D365 infolog messages method. There are several ways of doing this.

First, create a string variable, then pass it into the info(), warning(), or error() method.

static void displaySalesOrderFailedToInvoice(SalesId _salesId)
{
     str message = "The sales order with ID " + _salesId + " failed to be invoiced.";
     throw error(message);
}

Second, for an even better way, use the function strfmt() to take several variables and combine them together into one string. Notice the %1 is replaced with the next parameter passed into the strfmt method.

static void displaySalesOrderFailedToInvoice(SalesId _salesId)
{
    str messsage = strfmt("The sales order with ID %1 failed to be invoiced.", _salesId);
    throw error(messsage);
}

Conversion Methods

Notice that the function strfmt() can convert other variable data types to strings as well. Just add a ‘%1 %2 %3′, etc. Then, add each variable as a parameter to the strfmt() method in the corresponding order. The system will replace each %<number> with the variable’s value.

static void displayMessages()
{
     real r = 12.3456789;
     int  i = 17;
     utcDateTime utc = str2DateTime("2024-12-12 13:44:55" ,321); // 321 == YMD.
     str messsage = strFmt("Message: real = %1, int = %2, utcDateTime = %3, [%4]", r, i, utc);
     info(messsage);
    /**********  Actual Infolog output
    Message:  real = 12.35, int = 17, utcDateTime = 12/12/2024 01:44:55 pm, [%4]
    **********/
}

Of course, you can use conversion methods like int2str(), real2str(), int642str(). However, when supported, it is often easiest to just let strfmt() do the work on converting the variable to a string for you.

Random myRand = new Random(); 
int randomNumber;
randomNumber = myRand.nextInt();
str message = "My random number is " + int2str(randomNumber);
info(message);
//Instead use strfmt to convert the integer variable to a string and combine it with the larger message.
info(strfmt("My random number is %1", randomNumber));

Conditionally Enable Messages

Displaying enough D365 infolog messages is critical for understanding what went wrong in complicated processes with many branches inside the code. However, for end users, when the process is successful, too many messages can be overwhelming and unhelpful. So, how can developers get both?

The answer is to use a parameter to enable or disable extra messages conditionally.

In each module in Microsoft Dynamics 365 for Finance and Supply Chain, there exists a ‘parameters’ form and table. In this table and form, add a custom field to store whether the additional D365 infolog messages should display or not.

For example, add a field named EnableExtraMessages to the CustParameters table and form. Set the Enum Type property on the field to NoYes. This will cause it to show as a radio button on the form. The new field will show in the form with the menu item Accounts receivable parameters.

Next, see this code example:

CustParameters custParameters = CustParameters::find();
if (custParameters.EnableExtraMessages == NoYes::Yes)
{
     info("This is an example of an extra message that can be shown when it is needed.");
     info(strfmt("The RecId of the record that is currently being processed is %1.", custParameters.RecId));
}

Notice that when the parameter is unchecked, the additional info messages will not show. However, when the parameter is checked, the messages will show.

Most processes are simple enough that they do not require conditional enabling of the messages. However, if you encounter a process where you regularly are unclear about what the root cause of the issue is, consider adding verbose logging messages to help in those situations.

There are additional ways of adding logging to a process to help determine the root cause of an error. I plan to write several other articles on this topic.

Conclusion

Since showing D365 infolog messages to the user is so helpful, most developers learn these methods early. However, in my experience, developers often focus on adding messages to help during their testing and forget to add messages to help the end user. Additionally, messages should be added that include dynamic information, such as the ID of the record causing the issue. Therefore, it is important to understand how to use these methods and how to use messages to help end users solve any issues quickly.

Peter Ramer
Peter Ramer is a part of the Managed Application Services team at RSM working on Microsoft Dynamics 365. He focuses on the Retail and Commerce industries. When he is not solving problems and finding ways to accelerate his clients' business, he enjoys time with his three kids and amazing wife.

Share this:

One thought on “D365 Infolog Messages

Add yours

Leave a Reply

Your email address will not be published. Required fields are marked *

Proudly powered by WordPress | Theme: Baskerville 2 by Anders Noren.

Up ↑