Monday, November 14, 2022

#937 OIC Error Handling

Error handling is a big part of integration design. OIC allows one to catch faults at scope and global(integration) level. So when do we use what?

Let's look at a simple example - I have a synchronous integration with 2 scopes - 

This is another ubiquitous order process, scope 1 checks the validity of the country, scope 2 checks the product. The logic is very simple - the country name Ireland is invalid, we only accept the Gaelic versions √Čire or √Čireann.

Regarding Product - we are no longer accepting orders for our iScooter - too risky - a 300kmh scooter is not acceptable on any civilised footpath.

The checkCountry scope is as follows -

The scope also has a fault handler - it doesn't do much - just logs the fault.

The Product scope is similar, however, it does not implement the Fault Handler -

Finally, we look at the Global Fault handler - as the name suggests, this is at the integration level. Again, simple logic here -

Now I test with an order for Ireland - 

The order is processed successfully - 

I check out the activity stream - 

As you can see, the fault was thrown within the scope and caught the scope fault handler. Processing continues to the next scope - checkProduct.

Takeaway 1 

You can catch errors at scope level and continue processing, if that is your business requirement.
As you see, the Global error handler did not fire.

Next test is with an invalid product, the crazy iScooter.


Takeaway 2 

If you throw a fault in a scope without  fault handler, it automatically bubbles up to the Global Fault Handler.

Sometimes you might want both fault handlers to execute- the scope fault handler does some scope specific stuff, while the global fault handler may invoke a generic error handler.

This is easy - let's go back to the country scope and add a Re-throw fault action. Then test -  

Takeaway 3 

Rethrowing faults is a good idea if you have your generic fault/error processing defined in the Global Fault Handler.

Some Best Practices

To paraphrase the great George Orwell, all errors are equal but some are more equal than others. All errors should be thrown and then processed in a uniform manner. But what about the simple example of the invalidCountry we had? 

Here we could use the Scope Fault Handler to log this fault - e.g. order nr 1 had Ireland as destination country. We could also do the necessary repair e.g. assign Eire or Eireann to a variable and use this later in any potential mappings, for example, when creating the customer in Netsuite. Here we're classifying invalidCountry as NOT a blocking error. The Scope Fault Handler could also be used to create business relevant error messages - e.g. in case of Netsuite duplicate customer errors.

Capturing and Processing Errors  

I added a createNSCustomer scope to the integration. It invokes Netsuite to create a customer. Duplicates could be a potential issue - the error structure returned by Netsuite is as follows - 

Note that this response won't automatically trigger an error in the integration. check out the first <status isSuccess="true" /> This tells us, from a technical perspective, the Netsuite invoke worked. The second <status> is not set to success, Note the Netsuite specific error code - UNIQUE_CUST_ID_REQD. Finally, the message spells out what's wrong.

Error data is moved about via the OIC Fault Object; it's structure is as follows - 

My goal here is to inform the LOB owner, via her preferred channel,  about any errors in her area. The error message will need to be understandable from a business perspective.

This is where the Generic Error Handler integration comes in - as you can see, I have only implemented email notification, but this could be augmented with human intervention, via an invoke of an OIC Process to allow business users to view and possibly fix/resubmit errored integrations. 


So back to the original order processing integration - I need to do some work here, beginning with the createCustomer scope -
  • Check for Netsuite error
  • Businessify the error message
  • Set fields in fault structure
  • Bubble up the error to the global fault handler
In the global fault handler -
  • Invoke the Generic Error Handler integration passing the fault structure values.

I run the integration again, with the duplicate Netsuite customer -

And check my email - 


No comments: