5

I have some constraints in a postgresql database (unique, foreign key...).

I use spring data r2dbc repository : ReactiveCrudRepository

I would like to transform the DataIntegrityViolationException throw by the repository to some custom exception based on the constraintName in ErrorDetails field of PostgresqlDataIntegrityViolationException.

But ExceptionFactory class containing the PostgresqlDataIntegrityViolationException is package private. So I can't cast the cause exception of DataIntegrityViolationException to PostgresqlDataIntegrityViolationException.

What is the cleanest way to access to the constraintName when I catch a DataIntegrityViolationException ?

(something better than parsing the exception message ^^)

edit :

I'm ended with this solution :

    val DataIntegrityViolationException.pgErrorDetails: ErrorDetails
        get() = when(val cause = this.cause) {
                null -> error("cause should not be null")
                else -> cause.javaClass
                        .getDeclaredField("errorDetails")
                        .apply { isAccessible = true }
                        .let { it.get(cause) as ErrorDetails }
                }
fpa
  • 51
  • 3

1 Answers1

1
 Myr2dbcRepo.save(myEntity).doOnError(cause -> {
     PostgresqlException pe =(PostgresqlException) cause.getCause();
     ErrorDetails ed = pe.getErrorDetails();
 }).suscribe();

Take into account that DataIntegrityViolationException is just a spring boot wrapper for the dbDriver's Exceptions you're using, in this case R2DBC.

Also you may need to change the scope of R2DBC-POSTGRES dependency from "runtime" to "implementation".

Finally notice my code example is on java, I'm sure you won't have efforts translating it to kotlin.