For all you wild ones supporting an integration via API... what's a good standard for logging?

We have an integration I am trying to get live and troubleshooting has been a pain.

It works fine one week, the next week it doesn’t, etc… You know how external APIs go if you have an integration.

For those of you that wrote your own API calls, are you logging those payloads and responses from the API somewhere so you can review them? Or do you do that only if logging is turned on in your app, etc… FWIW we are making the calls from a form within Epicor.

Looking for a little help in how best to do this whole thing…

2 Likes

:no_mouth: that’s perfect.

And how did you know it was a shipping integration I was trying to log! :rofl: :thinking:

St Patricks Day Rainbow GIF by TipsyElves.com

Okay word so are you just writing updates to UD table at each try catch in the integration? Or whatever error handling/logic points that make sense?

Yup.

For example:

                  if( vSku.Trim().Equals("") )
                  {
                    string whse = (
                      from w in Db.Warehse
                      where w.Company == Session.CompanyID &&
                            w.WarehouseCode == whseCode
                      select w.Description).DefaultIfEmpty("").FirstOrDefault();
                  
                    headerKey = line.ship.PackNum.ToString();
                    detailKey = !Type.Equals("MiscShip") ? line.ship.PackLine.ToString() : line.deets.PackLine.ToString();
                    messageType = "Error";
                    message = "Part number " + pNum + " does not have a vendor part cross reference in warehouse '" + whse + "' (" + whseCode + ").";
                    partNum = pNum;
                    userID = !Type.Equals("MiscShip") ? orderInfo.EntryPerson : shipInfo.ship.EntryPerson;
                    
                    this.EfxLib.TPLIntegrations.WriteToUD15(source,
                                                           direction,
                                                           headerKey,
                                                           detailKey,
                                                           messageType,
                                                           message,
                                                           partNum,
                                                           action,
                                                           userID);
                    
                    continue;
                    
                  }

And in the catch:

  catch(Exception e)
  {
    Success = false;
    ErrorMsg = e.Message.ToString();
    InfoMsg = "";
    TPLRef = "";
    
    headerKey = shipInfo[0].ship.PackNum.ToString();
    detailKey = "";
    messageType = "Error";
    message = e.Message.ToString();
    partNum = "";
    userID = !Type.Equals("MiscShip") ? orderInfo.EntryPerson : shipInfo[0].ship.EntryPerson;
    
    this.EfxLib.TPLIntegrations.WriteToUD15(source,
                                           direction,
                                           headerKey,
                                           detailKey,
                                           messageType,
                                           message,
                                           partNum,
                                           action,
                                           userID);
  }

And everywhere else that I think it might be beneficial to have a message to act upon or know.

2 Likes

Thank you, okay. I like the function call too. Last I checked though if I want to do it on a form I have to make a rest call since I don’t have a business object that I can use.

This is an agnostic log table as well. I have every 3PL logging to this table and can be filtered on the Action column which shows Library~Function.

You can see the exact day I started working on a different integration, lol.

1 Like

Okay cool, thanks a ton for an example of how you are successfully doing it.

I just didn’t know if I should log in database, log on client, etc.

1 Like

I chose the database so that I can put the onus back on the users if it’s something they can act upon. Like–errors of the integration is something I will have to deal with, but if it’s something like a line shipped short–that’s on them. They can then make a dashboard and work from that vs having to go look up a log file on the server and deal with that.
I would avoid anything client-based as it makes it hard to debug if you don’t have access to the file and have to ask someone for it.

Hahaha yes those look like my recent attempts too :rofl:

But it’s funny cause the json response object was different just 3 days ago and now the field I am converting to a string no longer exists…

We are using a dev api so I guess it is what it is, probably changes somewhat frequently.

That logging table is Fire! :fire:

So Excited Reaction GIF by Originals

1 Like

Here’s the object in the response that they have listed on the API documentation:

"dispatch": {
"carrierId": "string",
"carrier": "string",
"carrierCode": "string",
"schedulePickup": true,
"bolStatus": "ok",
"pickupNum": "string",
"proNum": "string"
}

Here’s the actual response:

  "dispatch": {

    "carrier": "FedEx",

    "carrierId": "5304f480259b15a35400000c",

    "carrierCode": "fxfe",

    "schedulePickup": false,

    "bolStatus": "ok"

  },

Notice the “proNum” is missing, the very same field I am trying to convert to a string and use in other methods on my customization :sob:

So @utaylor it is fairly common for JSON based APIs to ommit null fields you should use a serializer that supports that behavior and always null check your objects

4 Likes

Thanks for the suggestion I will do that.

I have a serverless function in the Azure cloud which sits in the middle. The external systems calls that and then the function calls Epicor. It’s for sales orders and shipments. It has a log enabled by default and you can write there whatever you want. Very handy during the set-up & test process. Even now I always go and check the logs there first whenever I suspect something is wrong. I was reluctant doing this at first but I can say it was definitely worth it.
The first thing I do there is send the payload to an UD table in Epicor. Then, I do as much validation as I can before sending the call to Epicor. Probably too late for you as you’re almost live but it’s worth having a look.

2 Likes

It’s not too late, we are not live yet, it’s all still in a testing environment.

Thanks for the comment.

@hmwillett I was going to ask you about the payload of the rest call, do you have that in your UD table too, like Dragos is doing? And the response from the API?

I was waiting for @Mark_Wonsil to notice this one. Really cool Dragos that you are using a serverless function- go cloud!

Dope.
No, I don’t but I may add it now!

Unfortunately, I have not been so lucky as to get a REST integration. Jose stuck me with SOAP and SFTP. :sweat_smile:

1 Like