The problem is very simple: how do you smartly stop an XI graphical mapping? Suppose you volountarily want a graphical mapping step to fail based on certain conditions. You would throw an exception in a UDF (User Defined Function), yes, but XI doesn't allow you to add the throws clause in a UDF, so no way. Another easy way is to write a statement that will 100% fail, like: String youWillFail = new String("not.enough.long"); youWillFail.substring(0,100);
This would crash in a StringIndexOutOfBounds exception, the message would stop, but if you use this technique several times in your mapping, it's a nightmare - if even possible - to understand where it was exactly generated!
So writing a couple of Java classes, and importing a .jar file in Integration Repository as Imported Archive can easily solve the problem.
Step by step, here's what you need to do.
Create a java package with two classes inside: CustomMappingException and ExceptionThrower. Compile and export them as .jar file. Source code is below.
package com.guarneri.xi.mapping.udf; public class CustomMappingException extends RuntimeException { public CustomMappingException() { super(); } public CustomMappingException(String message) { super(message); } public CustomMappingException(Throwable cause) { super(cause); } public CustomMappingException(String message, Throwable cause) { super(message, cause); } } package com.guarneri.xi.mapping.udf; public class ExceptionThrower { public static void fire(String message) throws CustomMappingException { throw new CustomMappingException(message); } }
Note that the key of everything is to extend RuntimeException, and not Exception. Why? Because Java syntax check doesn't allow you to call a method throwing an Exception without surrounding it with a try catch. While our method- in this case the static ExceptionThrower.fire() - throws a RuntimeException, for which you can omit the try catch.
Once you have created the Imported Archive containing the two classe, you can build up a UDF that will use it, as shown in the picture below.
The choices upon which the UDF should hang the whole mapping are up to you. I chose to handle this three kind of problems:
- no incoming value
- empty incoming value
- forced exception, that is if you pass $error$ as first UDF argument
- otherwise the incoming value is returned, and the mapping happily continues its job.
Here's a sample mapping, where the first argument is the incoming value, and the second is a constant containing the Exception message ("No SalesOrderNumber was requested" here).
And now, the magic: in the Message Monitor (SXMB_MONI transaction) a qualified exception is reported!
If I were an XI day-by-day Admin, I would be pleased by such an option. 🙂