3.2.12.2. Передача исключений Middleware
Если при выполнении запроса от клиента на 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 {
...