public void run(String description,
Runnable operation) {
operations.push(description);
try
{
operation.run();
}
catch (RuntimeException ex)
{
if (!logged)
{
logger.error(InternalUtils.toMessage(ex));
logger.error("Operations trace:");
Object[] snapshot = operations.getSnapshot();
String[] trace = new String[snapshot.length];
for (int i = 0; i < snapshot.length; i++)
{
trace[i] = snapshot[i].toString();
logger.error(String.format("[%2d] %s", i + 1, trace[i]));
}
logged = true;
throw new OperationException(ex, trace);
}
throw ex;
}
finally
{
operations.pop();
// We've finally backed out of the operation stack ... but there may be more to come!
if (operations.isEmpty()) logged = false;
}
}
|