Если при выполнении запроса от клиента на Middleware возникает исключение, выполнение прерывается и на клиента возвращается объект исключения, как правило, включающий цепочку
порождающих друг друга исключений. Так как цепочка исключений может содержать классы, недоступные клиентскому блоку (например,
исключения JDBC-драйвера), на клиента передается не сама эта цепочка, а ее представление внутри специального создаваемого
исключения RemoteException
.
Информация об исключениях-причинах сохраняется в виде списка объектов RemoteException.Cause
. Каждый объект Cause
хранит обязательно имя класса исключения и его сообщение. Кроме того, если класс исключения "поддерживается клиентом", то
Cause
содержит также и сам объект исключения. Это дает возможность передать на клиента информацию в полях исключения.
Класс исключения, объекты которого нужно передавать на клиентский уровень именно в виде Java-объектов, нужно аннотировать
@SupportedByClient
, например:
@SupportedByClient public class WorkflowException extends RuntimeException { ...
Таким образом, при возникновении на Middleware исключения, не аннотированного @SupportedByClient
, вызывающий клиентский код получит RemoteException
, внутри которого будет находиться исходное исключение в виде строки. Если же исходное исключение аннотировано @SupportedByClient
, то вызывающий код получит именно его. Это дает возможность в прикладном коде организовывать обработку декларируемых сервисами Middleware исключений традиционным образом - с помощью блоков try...catch
.
Следует иметь в виду, что чтобы поддерживаемое клиентом исключение было действительно передано на клиента в виде объекта,
оно не должно содержать внутри себя в цепочке getCause()
неподдерживаемых исключений. Поэтому если вы создаете на Middleware экземпляр исключения и хотите передать его на клиента, указывайте для него параметр cause
только если вы уверены, что он содержит только исключения, известные клиенту.
Упаковку объектов исключений в RemoteException
перед передачей на клиентский уровень выполняет перехватчик вызовов сервисов - класс ServiceInterceptor
. Кроме того, он же выполняет логгирование исключений. По умолчанию в журнал выводится вся информация об исключении, включая
полный stack trace. Если это нежелательно, можно добавить классу исключения аннотацию @Logging
, указав в ней тип логгирования:
-
FULL
- (по умолчанию) полная информация, включая stacktrace -
BRIEF
- только имя класса исключения и сообщение -
NONE
- не выводить ничего
Например:
@SupportedByClient @Logging(Logging.Type.BRIEF) public class FinancialTransactionException extends Exception { ...