BPM error checking popup usings & references help

I don’t know how to get by this custom C# error. I’m trying to troubleshoot by popping open a message box but I can’t get the BPM to compile with the message box.

’FakeAsyncHost’ does not contain a definition for ‘PublishInfoMessage’ and no accessible extension method ‘PublishInfoMessage’ accepting a first agrument type ‘FakeAsyncHost’ could be found (are you missing a using directive or an assembly reference?)

What do I need to include to get PublishInfoMessage to work? Do I have to put something in usings & references.

// setup message box parameters: mbp

var mbp1 = "This is my message"; // text to appear on popup 
var mbp2 = Ice.Common.BusinessObjectMessageType.Information; //req'd don't change
var mbp3 = Ice.Bpm.InfoMessageDisplayMode.Individual; 
var mbp4 = ""; // text that appears in popup Details button ->program field 
var mbp5 = ""; // text that appears in popup Details button ->method field 


// Each ShipHead (should only be 1)
foreach(var sh_row in (from tt 
                   in ttShipHead 
                   where tt.RowMod == "U" 
                   select tt)) {
               
               
  // Each ShipDtl
  foreach(var sd_row in (from tt 
                     in Db.ShipDtl 
                     where tt.Company == sh_row.Company 
                        && tt.PackNum == sh_row.PackNum 
                     select tt)) {
   
   // HTTP POST to endpoint to reset the order rel meta
   
   //Create a list of your parameters
        var postParams = new List<KeyValuePair<string, object>>(){
                    new KeyValuePair<string, object>("db", "E10Train"),
                    new KeyValuePair<string, object>("company", sd_row.Company) ,
                    new KeyValuePair<string, object>("orderNum", sd_row.OrderNum), 
                    new KeyValuePair<string, object>("lineNum", sd_row.OrderLine),
                    new KeyValuePair<string, object>("relNum", sd_row.OrderRelNum)
                };
    mbp1 = sd_row.Company.ToString() + " " + sd_row.OrderNum.ToString(); 
    this.PublishInfoMessage(mbp1, mbp2, mbp3, mbp4, mbp5); 
    
   //Join KVPs into a x-www-formurlencoded string
        var formString = string.Join("&", postParams.Select(x => string.Format("{0}={1}", x.Key, x.Value)));
        //output: FirstParamter=FirstValue&SecondParamter=SecondValue
    
   //Encode form string to bytes
        var bytes = Encoding.UTF8.GetBytes(formString);
    
   //Create a POST webrequest
        var request = WebRequest.CreateHttp("http://our-endpoint-url-here");
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = bytes.Length;
    
   //Open request stream
        Stream dataStream = request.GetRequestStream();            
        dataStream.Write (bytes, 0, bytes.Length);
        dataStream.Close();        
  

  } // end ShipDtl foreach 

} // end ShipHead foreach

The most common method for debugging in Custom code in a BPM is to write to the event log.

edit

like:
Ice.Diagnostics.Log.WriteEntry(msg)

more details in topic:

Does anyone know where is the server event log is?

There are many things that say logs, so it’s confusing what is what.
Where does Ice.Diagnostics.Log.WriteEntry(msg) this write to?

It writes to the server hosting the E10 App pool.

that was generated from a DD BPM with a custom code widget :slight_smile:
image

Wouldn’t it be nice if there was a strategy that worked for cloud and on-prem users that logged everything to a single place that was searchable, looked for correlations among events (memory usuage, number of licenses, network speed, …), and notified you of the ones you’re interested in?

https://epicor-manufacturing.ideas.aha.io/ideas/ERP-I-139

2 Likes

I use something like this:

this.PublishInfoMessage("quote num: " + QuoteDtl.QuoteNum.ToString() + " line: " + QuoteDtl.QuoteLine.ToString() , Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, “”, “”);

You won’t see the message if you encounter an error, though.

Joe

If you’re cloud based, use a UD table as a logfile.

edit

Is it possible to have the server write a file to where files are accessible by “Server Download” (or whatever the E10 program is called that lets you download files from the server)?

Like the log file that is created when Generate PO Suggestions is run. If so, would that file appear as one you could select in the “Server Download” program?

Anything’s possible. But are log files that have to be downloaded and read by “hand”, a debug methodology just a little bit better than a MessageBox, the best way to go? Will devs voluntarily download these periodically to check to make sure everything is still working? For each and every log file written to? Is that how M365 works? Salesforce? G-Suite? It’s a band-aid but is that the way we want to develop?

I thought using MessageBox doesn’t work on server side code like a BPM. Or am I mistaken?

If not, having to download a file to get debugging info is better than using a MessageBox that never appears.

Side question… Would a messagebox (called from server side code) appear to a user running the client on the App server?

Sorry, my sarcasm meter is out of spec.

Not a fan of MessageBox debugging. :face_vomiting: I know we grew up on it in mnmmmn-ties but debugging tools have gotten much, much better. The biggest mindset change is monitoring for errors in production and not just during development. Users find random message boxes (even regular Error dialogs) a bit unsettling.

Also… My use of “Debugging” was really meant as “developing”. Like when you want to know the value of a variable after your code did some magic on it. I call it “debugging”, because it’s most often added during development, when things aren’t working as desired. And “not working as desired”, is pretty much the definition of a bug.

Yep, I’m with you.

But let’s say I had a bug due to an uninitialized variable. I found out where that happened and I fixed it. I put in a bunch of message boxes to find the source and now I’ve taken them out.

But it happens again. The user emails you the error. “Can you click on Details?” “Oh, I already closed the dialog”. “Well, when it happens again, please click on Details and send it to me.”

Next time it happens, we add some logging that checks to see if the variable is initialized. We have an open window that displays the log messages in real time. We have a history of every run and can see what changes as we fixed the bug. We leave conditional logging in there to catch the uninitialized variable in the future.

Some day, the variable is not initialized. We log the error, the username running the command, and the stack trace. We present the user with a message that says, “Hey. That didn’t work out. We know where the error occurred and we’ve already sent the developer all of the details. We’ll be in contact as soon as we have a resolution.” We had a notification set up in the logging system to send an alert (configurable by urgency: email, text, pager, whatever…). We go to the logging system and we see the error. We can also see from another log super-imposed on this one what the CPU and memory was like at the time. We were also logging the number of users. Uh oh. We’ve exceeded the number of logins. A call silently failed and the variable wasn’t initialized. Hmmm. Some times bugs are environmental and tough to reproduce at the developer’s desktop with everything running locally. Explains why we say, “Hmm. It works on my environment…” :thinking:

Like I said, there’s room for improvement here that would benefit both Epicor and their users.

Oh, there’s a whole lot to be said about testing here but that’s a whole other long :peach: post.

Separately, when Epicor uses just .Net Core, this stuff becomes available: Introducing dotnet-monitor, an experimental tool - .NET Blog

On sales order form ( very customized for us…) I use an email direct to me catching any errors, with all the error details and more.

Also for BPM’s I log into a temp file on the server. I write state of variables at different locations in code. Helps debug if anything bizarre happens…

I can disable the loggin as well…

Pierre

And hopefully you’re always around to get that email! :wink:

1 Like

I typically simplify the code to:

PublishInfoMessage("This is my message",0,0,"","");

The zeros are simply the enum values of what you already had.

Also, I see people using the object “this” when they post BPM code. I never do. Not sure what is different, but I never have the issues others have.

Are you trying to throw a msg box in a custom code box marked to run Async? If so, switch it to sync to see. Async runs off the UI thread so message box code will not compile. “’FakeAsyncHost” tells me this code block is marked as such. You will need to write to the event log if you want to debug in async mode, but i much prefer debugging in Visual Studio in sync mode first, then switch to async