我有一個自定義建議來處理從REST API 錯誤處理復制的控制器的例外,以及一個處理 DataIntegrityViolationException 的方法:
@ExceptionHandler(DataIntegrityViolationException.class)
protected ResponseEntity<Object> handleDataIntegrityViolation(DataIntegrityViolationException ex,
WebRequest request) {
if (ex.getCause() instanceof ConstraintViolationException) {
return buildResponseEntity(new ApiError(HttpStatus.CONFLICT, "Database error", ex));
}
return buildResponseEntity(new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex));
}
ApiError - 建構式
public ApiError(HttpStatus status, String message, Throwable ex) {
this();
this.status = status;
this.message = message;
this.debugMessage = ex.getLocalizedMessage();
}
當發生錯誤時,回應會顯示如下訊息:
"apierror": {
"status": "CONFLICT",
"message": "Database error",
"debugMessage": "could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",
"constraintName": null
}
問題是該訊息沒有向消費者顯示真正的問題,因為真正的問題在 ( ex.getCause().getCause().getMessage())內部:
Cannot delete or update a parent row: a foreign key constraint fails
(`cup_orchestrator`.`cpo_production_cycle`, CONSTRAINT `fk_cpo_production_cycle_cpo_cycle_type1`
FOREIGN KEY (`cycle_type_id`) REFERENCES `cpo_cycle_type` (`cycle_type_id`))
我想處理這樣的訊息:“記錄仍然有來自其他表的參考”;
是否有任何自定義處理程式例外以更具體的方式處理 sql 例外?
uj5u.com熱心網友回復:
我已將 DataIntegrityViolationException 句柄更改為更具體:
@ExceptionHandler(DataIntegrityViolationException.class)
protected ResponseEntity<Object> handleDataIntegrityViolation(DataIntegrityViolationException ex,
WebRequest request) {
Throwable cause = ex.getRootCause();
if (cause instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException consEx = (SQLIntegrityConstraintViolationException) cause;
String message = "";
String constraint = "";
HttpStatus httpStatus = null;
if (consEx.getMessage().contains("UNIQUE")) {
message = "Cannot enter the same record twice";
constraint = "DUPLICATED_RECORD";
httpStatus = HttpStatus.CONFLICT;
} else if (consEx.getMessage().contains("foreign key constraint")) {
message = "Record still have reference from other table";
constraint = "USED_RECORD";
httpStatus = HttpStatus.UNPROCESSABLE_ENTITY;
}
return buildResponseEntity(new ApiError(httpStatus, message, consEx.getMessage(), constraint));
} else if (ex.getCause() instanceof ConstraintViolationException) {
return buildResponseEntity(new ApiError(HttpStatus.CONFLICT, "Database error", ex));
}
return buildResponseEntity(new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, ex));
}
我在 ApiError 類和建構式上創建了一個約束屬性來接收:
public ApiError(HttpStatus status, String message, String debugMessage, String constraint) {
this.status = status;
this.message = message;
this.debugMessage = debugMessage;
this.constraint = constraint;
}
在反應應用程式將創建一個捆綁到這個約束:
DUPLICATED_RECORD
USED??_RECORD
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/324115.html
