DomUI

ExceptionDialog

What the user sees when code threw. It shows a box with the message you passed as its title, and what it puts inside depends on whether anything recognises the exception.

try {
	save();
} catch(Exception x) {
	ExceptionDialog.create(this, "Saving the order failed", x);
}

Showing one

Method What it does
ExceptionDialog.create(NodeContainer, String message, Throwable) show the exception in a box
ExceptionDialog.createIgnore(NodeContainer, String message, Throwable) the same, but a failure while making the box is logged instead of thrown
node.executeWithDialog(String message, IExecute) run the code, show the dialog if it threw, and return false in that case

executeWithDialog is on NodeContainer, so it is available on every page and component; it is the try/catch above, written once:

cp.add(new DefaultButton("Save", () -> executeWithDialog("Saving the order failed", () -> save())));

A ValidationException is ignored on purpose: the control that threw it has already put its message on the screen, and a box on top of that would say the same thing twice.

What ends up in the box

The exception is unwrapped out of any WrappedException and offered to the registered translators - functions from an exception to an ExceptionPresentation, which is either a sentence or a piece of DOM. The first one that returns something decides what is shown. If none of them recognise it, the exception is logged as an error and the box shows its toString() and its stack trace.

Exception What the user sees instead of a stack trace
CodeException, MessageException the message of the exception, translated
QConcurrentUpdateException, JPA's OptimisticLockException "somebody else changed this data"
a SQLException with SQL state 23505, BetterSQLException the message of the database error

Your own exceptions get the same treatment by registering a translator:

ExceptionDialog.register(x -> x instanceof OutOfStockException osx
	? new ExceptionPresentation(Msg.orderOutOfStock.format(osx.getAlbum()))
	: null);

The list is global and the last translator registered is asked first, so this belongs in the initialize() of your DomApplication - it is a decision of the application, not of a page.

Exceptions that nobody catches at all do not reach this class; they are handled by the exception listeners of the application, which telling something to a user describes.

Last modified: 2026/09/06