最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to Retrieve Root Cause of PSQLException in Quarkus with JTA - Stack Overflow

programmeradmin2浏览0评论

I am using Quarkus 3.19 with JTA, and I am trying to catch PSQLException using a @ServerExceptionMapper.

Here’s my exception handler:

@ServerExceptionMapper
public RestResponse<ErrorMessage> handleRollbackException(QuarkusTransactionException exception) {
    Throwable cause = exception;
    while (cause.getCause() != null && cause.getCause() != cause) {
        cause = cause.getCause();
    }
    log.info(cause.getClass()
            .getName() + "\n" + cause.toString());
    var message = ErrorMessage.builder()
            .type("/service/transaction-exception")
            .title("Could not persist data")
            .status(Response.Status.CONFLICT)
            .detail(cause.getMessage())
            .instance(String.format("%s:%s", applicationName, cause.getMessage()))
            .build();
    return RestResponse.status(message.getStatus(), message);
}

However, the issue is that my application throws a QuarkusTransactionException, which wraps a RollbackException.

The log displayed by the mapper is

INFO  requestId= processId= [co.nx.po.op.ws.er.QuarkusExceptionMappers] (vert.x-eventloop-thread-1) jakarta.transaction.RollbackException
jakarta.transaction.RollbackException: ARJUNA016053: Could not commit transaction.

Unfortunately, RollbackException does not provide any useful details about the original PSQLException. I get the following message in the log file

WARN  requestId= processId= [co.ar.at.jta] (vert.x-eventloop-thread-1) ARJUNA016039: onePhaseCommit on < formatId=131077, gtrid_length=35, bqual_length=36, tx_uid=0:ffff7f000101:9b09:67e27ea9:32, node_name=quarkus, branch_uid=0:ffff7f000101:9b09:67e27ea9:35, subordinatenodename=null, eis_name=0 > (io.agroal.narayana.LocalXAResource@490a4005) failed with exception XAException.XA_RBROLLBACK: javax.transaction.xa.XAException: Error trying to transactionCommit local transaction: ERROR: update or delete on table "postmaster_fact_definition" violates foreign key constraint "postmaster_condition_fact_fk" on table "postmaster_condition"
  Detail: Key (id)=(crm_main_contract_number) is still referenced from table "postmaster_condition".
    at io.agroal.narayana.XAExceptionUtils.xaException(XAExceptionUtils.java:20)
    at io.agroal.narayana.XAExceptionUtils.xaException(XAExceptionUtils.java:8)
    at io.agroal.narayana.LocalXAResourcemit(LocalXAResource.java:73)
    at com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord.topLevelOnePhaseCommit(XAResourceRecord.java:631)
    at com.arjuna.ats.arjuna.coordinator.BasicAction.onePhaseCommit(BasicAction.java:2477)
    at com.arjuna.ats.arjuna.coordinator.BasicAction.End(BasicAction.java:1542)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:71)
Caused by: .postgresql.util.PSQLException: ERROR: update or delete on table "postmaster_fact_definition" violates foreign key constraint "postmaster_condition_fact_fk" on table "postmaster_condition"
  Detail: Key (id)=(crm_main_contract_number) is still referenced from table "postmaster_condition".
    at .postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2733)
    at .postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2420)
    at .postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372)
    at .postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:330)
    at .postgresql.jdbc.PgConnection.executeTransactionCommand(PgConnection.java:981)
    at .postgresql.jdbc.PgConnectionmit(PgConnection.java:1003)
    at io.agroal.pool.ConnectionHandler.transactionCommit(ConnectionHandler.java:348)
    at io.agroal.narayana.LocalXAResourcemit(LocalXAResource.java:70)
    ... 49 more

How can I retrieve the original PSQLException that caused the rollback?

Any insights or best practices would be greatly appreciated!

I am using Quarkus 3.19 with JTA, and I am trying to catch PSQLException using a @ServerExceptionMapper.

Here’s my exception handler:

@ServerExceptionMapper
public RestResponse<ErrorMessage> handleRollbackException(QuarkusTransactionException exception) {
    Throwable cause = exception;
    while (cause.getCause() != null && cause.getCause() != cause) {
        cause = cause.getCause();
    }
    log.info(cause.getClass()
            .getName() + "\n" + cause.toString());
    var message = ErrorMessage.builder()
            .type("/service/transaction-exception")
            .title("Could not persist data")
            .status(Response.Status.CONFLICT)
            .detail(cause.getMessage())
            .instance(String.format("%s:%s", applicationName, cause.getMessage()))
            .build();
    return RestResponse.status(message.getStatus(), message);
}

However, the issue is that my application throws a QuarkusTransactionException, which wraps a RollbackException.

The log displayed by the mapper is

INFO  requestId= processId= [co.nx.po.op.ws.er.QuarkusExceptionMappers] (vert.x-eventloop-thread-1) jakarta.transaction.RollbackException
jakarta.transaction.RollbackException: ARJUNA016053: Could not commit transaction.

Unfortunately, RollbackException does not provide any useful details about the original PSQLException. I get the following message in the log file

WARN  requestId= processId= [co.ar.at.jta] (vert.x-eventloop-thread-1) ARJUNA016039: onePhaseCommit on < formatId=131077, gtrid_length=35, bqual_length=36, tx_uid=0:ffff7f000101:9b09:67e27ea9:32, node_name=quarkus, branch_uid=0:ffff7f000101:9b09:67e27ea9:35, subordinatenodename=null, eis_name=0 > (io.agroal.narayana.LocalXAResource@490a4005) failed with exception XAException.XA_RBROLLBACK: javax.transaction.xa.XAException: Error trying to transactionCommit local transaction: ERROR: update or delete on table "postmaster_fact_definition" violates foreign key constraint "postmaster_condition_fact_fk" on table "postmaster_condition"
  Detail: Key (id)=(crm_main_contract_number) is still referenced from table "postmaster_condition".
    at io.agroal.narayana.XAExceptionUtils.xaException(XAExceptionUtils.java:20)
    at io.agroal.narayana.XAExceptionUtils.xaException(XAExceptionUtils.java:8)
    at io.agroal.narayana.LocalXAResourcemit(LocalXAResource.java:73)
    at com.arjuna.ats.internal.jta.resources.arjunacore.XAResourceRecord.topLevelOnePhaseCommit(XAResourceRecord.java:631)
    at com.arjuna.ats.arjuna.coordinator.BasicAction.onePhaseCommit(BasicAction.java:2477)
    at com.arjuna.ats.arjuna.coordinator.BasicAction.End(BasicAction.java:1542)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:71)
Caused by: .postgresql.util.PSQLException: ERROR: update or delete on table "postmaster_fact_definition" violates foreign key constraint "postmaster_condition_fact_fk" on table "postmaster_condition"
  Detail: Key (id)=(crm_main_contract_number) is still referenced from table "postmaster_condition".
    at .postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2733)
    at .postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2420)
    at .postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372)
    at .postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:330)
    at .postgresql.jdbc.PgConnection.executeTransactionCommand(PgConnection.java:981)
    at .postgresql.jdbc.PgConnectionmit(PgConnection.java:1003)
    at io.agroal.pool.ConnectionHandler.transactionCommit(ConnectionHandler.java:348)
    at io.agroal.narayana.LocalXAResourcemit(LocalXAResource.java:70)
    ... 49 more

How can I retrieve the original PSQLException that caused the rollback?

Any insights or best practices would be greatly appreciated!

Share Improve this question edited Mar 25 at 10:13 Joao Violante asked Mar 19 at 8:18 Joao ViolanteJoao Violante 112 bronze badges 4
  • Please provide both stacktraces: the RollbackException you're probably seeing in logs, and the PSQLExcetpion (which you can probably send to the console using debug mode and e.printStackTrace()). Also: do you use XA transactions? – yrodiere Commented Mar 19 at 12:39
  • You're right, there is a more usefull log and I use XA. I've updated original message with the log messages. – Joao Violante Commented Mar 25 at 10:14
  • Right, Narayana loves its logs. Feel free to report this (getting a log instead of a proper exception cause) as a bug: github/quarkusio/quarkus/issues I've personally tried to make this point already, but didn't get enough momentum. I think the Narayana team did try to improve things sometime last year, but maybe there are still some areas with logging only. – yrodiere Commented Mar 25 at 10:20
  • 1 github/quarkusio/quarkus/issues/46992 – Joao Violante Commented Mar 25 at 13:51
Add a comment  | 

1 Answer 1

Reset to default 0

You need to iterate over the causes of the exception and print that out.

Something like this:

private String getMessage(Exception e) {
        var result = e.getMessage();
        var cause = e.getCause();
        var maxDepth = 3;
        while (cause != null && maxDepth-- > 0) {
            result = cause.getMessage();
            cause = cause.getCause();
        }
        return result;
    }

Replace the 3 with your own logic.

See my exceptionmapper here:

https://github/quarkiverse/quarkus-fluentjdbc/blob/main/examples/src/main/java/com/acme/fluentjdbc/config/ExceptionMapper.java

发布评论

评论列表(0)

  1. 暂无评论