我正在使用 Mutiny 进行反应式编程开发 Quarkus 应用程序,并且在服务层中遇到异常处理问题。我有一个保留用户的方法,并且我想根据发生的错误类型抛出特定的异常。然而,我遇到了以下挑战:
以下是相关代码片段:
public Uni<AuthResponse> persistUser(User user) {
return Panache.withTransaction(user::persist)
.onItem().transform(success -> {
log.info("Successfully created user, email: {}", user.getEmail());
return new AuthResponse(user);
})
.onFailure(ConstraintViolationException.class)
.transform(ex -> handleUserCreationError(user.getEmail()))
.onFailure()
.transform(ex -> handleGeneralPersistenceError(ex, user.getEmail()));
}
private Throwable handleUserCreationError(String email) {
log.error("User already exists, email: {}", email);
return new AccountAlreadyExistsException(ExceptionMessages.ACCOUNT_ALREADY_EXISTS + email);
}
private Throwable handleGeneralPersistenceError(Throwable ex, String email) {
log.error("Error occurred while creating user: {}, exception: {}",email, ex.getMessage());
return new PersistenceException("Failed to create user", ex);
}
问题: 多个异常:如果不使用.transform(),发生ConstraintViolationException时会抛出多个异常。 两个变换均已触发:当我使用 .transform() 时,两个变换块都会被触发,这不是所需的行为。
期望的行为: 我想确保当ConstraintViolationException发生时,只调用handleUserCreationError,而不会继续调用handleGeneralPersistenceError。此外,我想根据错误类型抛出适当的异常,而不会导致多个异常。
我怎样才能实现这个目标? 任何有关如何在这种情况下正确处理异常的帮助或见解将不胜感激!
handleGeneralPersistenceError
正在被调用,因为这是一个不与任何特定类型绑定的异常处理程序,因此这是预料之中的,因为前一个 onFailure(Class).transform(...)
将一个异常映射到另一个异常,并且它在管道中转发到 onFailure().transform(...)
。
我建议你简单地将逻辑压缩为形式的单个转换:
onFailure().transform(err -> {
if (err instanceof X) {
// ...
} else if (err instanceof Y) {
// ...
}
})