如何在JAX-RS异常映射器中找出负责事务回滚的原始异常

问题描述

情况是什么:Wildfly 15上部署了REST API和EJB服务器bean。REST调用启动事务并触发自定义CDI事件。在我的服务器bean中,有一个事务观察者方法,其事务阶段为BEFORE_COMPLETION。在某些情况下,在此方法内部有意引发带有特定消息的自定义类型的运行时异常。我希望在这种情况下,事务将被回滚(也可以正确发生)。触发回滚的异常,我想在JAX-RS异常映射器中处理,最后从异常发送特定的HTTP响应代码和消息。

现在,几乎所有东西都可以按我的意愿工作:事务被回滚,异常映射器方法跳入并处理异常。

但是我最大的问题是:我在异常映射器中作为参数接收到的异常的类型为javax.transaction.RollbackException,而不是最初引发的预期自定义类型。确切的消息是:“ javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.”另外,我的例外似乎没有嵌套在任何地方,例如作为原因或在接收到的异常的调用堆栈中,因此我无法弄清楚我的消息是什么,并且由于其他原因(例如数据库错误等),我也无法将这种回滚与其他潜在的回滚区分开来

问题:上述我想要的想法完全可能吗?也许由于我缺乏Java EE经验,我完全误解了框架是如何工作的,而这种情况从根本上无法以这种方式工作?知道这已经对我有所帮助。否则,我应该怎么做才能使其正常工作,或者如何通过其他方法来达到预期的效果?

这是我当前的代码:

服务器Bean

import javax.ejb.Stateless;
import javax.enterprise.event.Observes;
import javax.enterprise.event.TransactionPhase;
import javax.transaction.Transactional;

import my.custom.package.CustomRuntimeException

@Stateless
@Transactional
public class CustomBean
{
    public void onNewCustomEvent(
        @Observes( during = TransactionPhase.BEFORE_COMPLETION ) CustomEvent event )
    {
        // do something
        
        if ( isSomeError )
        {
            throw new CustomRuntimeException("Some important detail message.");
        }
    }
}

异常映射器

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class CustomRuntimeExceptionMapper implements ExceptionMapper< Throwable >
{
    @Override
    public Response toResponse( Throwable e ) // <--- Expect: CustomRuntimeException,receive: RollbackException
    {
        // evaluate the exception and send proper HTTP code
        return Response.status( Response.Status.NOT_FOUND ).build();
    }
}

异常类

public class CustomRuntimeException extends RuntimeException
{
    public CustomRuntimeException(String errorReason)
    {
        super (errorReason);
    }
}

2020-08-17。补充说明。 在服务器日志中,我注意到了该错误消息,也许有助于更好地了解原因。我用谷歌搜索,但是找不到有用的东西。

WELD-000401: Failure while notifying an observer [UnbackedAnnotatedMethod] public CustomBean.onCustomEvent(@Observes CustomEvent) of event null.
 CustomRuntimeException

解决方法

实际上,您可以将此注释放在您的自定义异常上

@javax.ejb.ApplicationException(rollback=true)
public class CustomRuntimeException extends RuntimeException{...}

以便将异常直接报告给客户端(未包装)。

默认情况下,EJB容器将通过EJBException包装您的自定义异常,并且使用此批注将不会包装该异常。

但是在您的情况下,可能还有另一个异常或回滚的原因,而不是CustomAppException尝试调试代码执行以找出实际情况或提供完整代码,以便我们提供帮助。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...