@@ -107,7 +107,7 @@ protected boolean isConstraintViolationException(
107
107
Throwable throwable , Consumer <String > useMessage ) {
108
108
if (throwable == null ) return false ;
109
109
if (throwable instanceof SQLException sqlexc ) {
110
- useMessage .accept (sqlexc .getMessage ());
110
+ useMessage .accept ("SQL State: %s. %s" . formatted ( sqlexc .getSQLState (), sqlexc . getMessage () ));
111
111
/*
112
112
* Postgres error codes: https://www.postgresql.org/docs/13/errcodes-appendix.html
113
113
*
@@ -123,7 +123,7 @@ protected boolean isConstraintViolationException(
123
123
: false ;
124
124
}
125
125
126
- protected ProblemHint getHint (Throwable throwable ) {
126
+ protected ProblemHint getHint (Throwable throwable , Consumer < String > passSqlState ) {
127
127
if (throwable == null ) return ProblemHint .NONE ;
128
128
if (throwable instanceof SQLException sqlexc ) {
129
129
/*
@@ -135,11 +135,14 @@ protected ProblemHint getHint(Throwable throwable) {
135
135
case "23505" -> ProblemHint .UNIQUE_VIOLATION ;
136
136
case "23514" -> ProblemHint .MANDATORY_CHECK_FAILED ;
137
137
case "23502" -> ProblemHint .PROPERTY_MUST_NOT_BE_NULL ;
138
- case "40001" -> ProblemHint .RETRY_RECOMMENDED ;
139
- default -> ProblemHint .NONE ;
138
+ case "40000" , "40001" , "40002" , "40003" , "40P01" -> ProblemHint .RETRY_RECOMMENDED ;
139
+ default -> {
140
+ if (passSqlState != null ) passSqlState .accept (sqlexc .getSQLState ());
141
+ yield ProblemHint .NONE ;
142
+ }
140
143
};
141
144
} else if (throwable .getCause () != null ) {
142
- return getHint (throwable .getCause ());
145
+ return getHint (throwable .getCause (), passSqlState );
143
146
} else {
144
147
return ProblemHint .NONE ;
145
148
}
@@ -174,14 +177,18 @@ private void execInsertUpdate(
174
177
} catch (StatementException e ) {
175
178
AtomicReference <String > constraintMessage = new AtomicReference <>();
176
179
if (isConstraintViolationException (e , constraintMessage ::set )) {
177
- throw new ValidationException (constraintMessage .get (), getHint (e ));
180
+ throw new ValidationException (constraintMessage .get (), getHint (e , null ));
178
181
}
179
182
180
183
String detailMessage = e .getCause () != null ? e .getCause ().getMessage () : e .getMessage ();
184
+ AtomicReference <String > sqlState = new AtomicReference <>("None" );
185
+ ProblemHint hint = getHint (e , sqlState ::set );
181
186
throw new RepositoryException (
182
- String .format ("SQL exception: %s" , detailMessage ), e , getHint ( e ) );
187
+ String .format ("SQL State: %s; exception: %s" , sqlState . get (), detailMessage ), e , hint );
183
188
} catch (JdbiException e ) {
184
- throw new RepositoryException (e , getHint (e ));
189
+ AtomicReference <String > sqlState = new AtomicReference <>("None" );
190
+ ProblemHint hint = getHint (e , sqlState ::set );
191
+ throw new RepositoryException ("SQL State: %s" .formatted (sqlState .get ()), e , hint );
185
192
}
186
193
}
187
194
0 commit comments