I have a simple Epicor Function for creating a new record. A user had an error that I traced back to this function. Instead of the function catching the error and returning it, it escaped and they got an unhandled exception “We aplogize..”
The error I found in the server log was System.Transactions.TransactionAbortedException: The transaction has aborted.
try
{
this.CallService<Ice.Contracts.UD14SvcContract>(UD14svc =>
{
var ds = new UD14Tableset();
var UI = Guid.NewGuid().ToString();
UD14svc.GetaNewUD14(ref ds);
ds.UD14[0].Key1 = this.Quote;
ds.UD14[0].Key2 = this.QuoteLine;
ds.UD14[0].Key3 = this.Configuration ;
UD14svc.Update(ref ds);
var ds2 = UD14svc.GetByID(this.Quote,this.QuoteLine,this.Configuration,"","");
this.returnObj = ds2;
this.error = "No error";
});
}
catch (Exception e)
{
error = e.ToString();
}
This user is super click happy so I was wondering if somehow they hit the button twice and there was two new records in scope with the same keys both trying to be committed? Seems super unlikely but I can’t see what could go wrong here.
You mean when the function is returning? I would think the transaction scope would have been closed by then. The line this.returnObj = ds2; should be inside the try/catch block I would think
Right, I don’t think it’s getting the error when you set the value. But it then returns the value. But it will then exit the Try/Catch, and return the response parameter outside the Try/Catch, but still within the Transaction Scope
You might be able to get a more useful error message if you check inner exceptions, and also output the exception type, it may be a specific type of exception that contains more detail on either the outer or inner. unfortunately that would require duplicating, though.
Try an exception block like this too, it will walk through inner exceptions, and also output the exception type.
If it is a specifically typed Exception, you can handle it appropriately for more info.
} catch (Exception ex) {
var exinfo = "";
for (var cur = ex; cur != null; cur = cur.InnerException)
exinfo += $"[Level {level++}] Type: {cur.GetType().Name} | Msg: {cur.Message} | Stack: {cur.StackTrace}\n";
log($"Exception: {exinfo}");
}
} catch (Epicor.Customization.CompilationException ex) {
string xi = "";
foreach (var msg in ex.ExceptionMessageList) {
foreach (var str in msg.Errors) {
xi += $"Error: {str}\r\n ";
}
}
log(xi);
}