ConstraintViolationException handler isn't executed in Micronaut

扶醉桌前 提交于 2021-02-19 03:48:04

问题


I have a ConstraintViolationException handler class that looks like this:

@Produces
@Singleton
@Requires(classes = {ConstraintViolationException.class, ExceptionHandler.class})
public class ConstraintsViolationsExceptionHandler
        implements ExceptionHandler<ConstraintViolationException, HttpResponse> {

    @Override
    public HttpResponse
    handle(HttpRequest request, ConstraintViolationException exception) {
        return HttpResponse
                .status(HttpStatus.FORBIDDEN)
                .contentType(MediaType.APPLICATION_JSON)
                .characterEncoding("UTF-8")
                .body(new SignUpPhoneNumberErrorResponse<>(400,
                        "Wrong data used",
                        new ArrayList<>(exception.getConstraintViolations())));
    }
}  

where SignUpPhoneNumberErrorResponse is my error handling POJO which is getting serialized to JSON absolutely fine.

My Controller looks like this:

@Controller(PhoneAuthAndLoginConstants.CONTROLLER_BASE_PATH)
@Validated
public class UserPhoneNumberRegistrationAndLoginController {

    @Inject
    MongoDbUserSignUpPhoneNumberDAO mongoDbUserSignUpPhoneNumberDAO;

    @Post(uri = PhoneAuthAndLoginConstants.CONTROLLER_SIGN_UP_PATH,
            consumes = MediaType.APPLICATION_JSON,
            produces = MediaType.APPLICATION_JSON)
    public Single<ResponseDataEncapsulate>
    signUpForPhoneVerification(@Valid @Body UserSignUpPhoneNumberEntity phoneNumber) {
        return mongoDbUserSignUpPhoneNumberDAO.sendVerification(phoneNumber);
    }

    @Post(uri = PhoneAuthAndLoginConstants.CONTROLLER_SIGN_UP_PATH
            +
            PhoneAuthAndLoginConstants.CONTROLLER_SIGN_UP_VERIFICATION_CODE_PARAM,
            consumes = MediaType.APPLICATION_JSON,
            produces = MediaType.APPLICATION_JSON)
    public Single<ResponseDataEncapsulate>
    sendUserSignUpConfirmation(@Valid @Body UserAccountStateSignUpEntity verificationData,
                               HttpHeaders httpHeaders) {
        return mongoDbUserSignUpPhoneNumberDAO.signUp(verificationData);
    }
}  

My POJO for UserAccountStateSignUpEntity looks like this:

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserAccountStateSignUpEntity implements UserSignUpEntity {
    @NotNull @NotBlank @Size(min = 5, max = 13) private String phoneNumber;
    @NotNull @NotBlank @Size(min = 7, max = 7) private String verificationCode;
    @JsonIgnore private Boolean verifiedAccount = Boolean.FALSE;

    public UserAccountStateSignUpEntity(String phoneNumber, String verificationCode) {
        this.phoneNumber = phoneNumber;
        this.verificationCode = verificationCode;
        this.verifiedAccount = Boolean.TRUE;
    }

    @Override
    public Map<String, Object> makePhoneEntityMapForMongo() {
        HashMap<String, Object> returnMap = new HashMap<String, Object>() {{
            put("phoneNumber", phoneNumber);
            put("verificationCode", verificationCode);
            put("verifiedAccount", verifiedAccount);
        }};

        return Collections.unmodifiableMap(returnMap);
    }
}  

I send in a request payload like this:

{
    "phoneNumber" : "91-123456789",
    "verificationCode" : "18887"
}  

This should trigger a ConstraintViolationException and my handler code should execute and I should get a HTTP Forbidden. But instead I get the default HTTP Bad Request error message.

Why isn't my handler getting executed? What can be done to make it execute?

I'm using Micronaut 1.1.3 as the web framework and the Hibernate Validator as the javax.validation implementation.


回答1:


@Error that can be applied to method to map it to an error route and SignUpPhoneNumberErrorResponse would be returned as a error response body when any ConstraintViolationException occured.

For more detail visit Micronaut docs

@Controller("/${path}")
@Validated
public class UserPhoneNumberRegistrationAndLoginController {

    @Post
    public HttpResponse method(@Valid @Body UserAccountStateSignUpEntity verificationData, HttpHeaders httpHeaders) {
        return null;
    }

    @Error(exception = ConstraintViolationException.class)
    public SignUpPhoneNumberErrorResponse onSavedFailed(HttpRequest request, ConstraintViolationException ex) {
        return new SignUpPhoneNumberErrorResponse(500,
                        "Wrong data used",
                        String.valueOf(ex.getConstraintViolations().stream().map( e -> e.getPropertyPath()+": "+e.getMessage()).collect(Collectors.toList())),
                "Application",
                "Error",
                System.currentTimeMillis());
    }

    @Error(status = HttpStatus.NOT_FOUND, global = true)  
    public HttpResponse notFound(HttpRequest request) {
        //return custom 404 error body
    }

} 



回答2:


I removed the @Requires(classes = {ConstraintViolationException.class, ExceptionHandler.class}) annotation and replaced the ArrayList<> in the body with a comma separated string and it started to work fine. Although I do not know the consequences of removing the annotation.




回答3:


I recently had the same problem with error handling in Micronaut. As I figured out, there is not a org.hibernate.exception.ConstraintViolationException thrown, but a javax.persistence.PersistenceException.

For me, then it worked with @Error(exception = PersistenceException::class) (Kotlin).




回答4:


@Error annotation handling for ConstraintViolationException worked for me only when it is on controller.

In the end managed to handle it like this, by replacing the micronaut ConstraintExceptionHandler bean:

@Produces
@Replaces(io.micronaut.validation.exceptions.ConstraintExceptionHandler.class)
@Requires(classes = {ConstraintViolationException.class, ExceptionHandler.class})
public class ConstraintExceptionHandler extends io.micronaut.validation.exceptions.ConstraintExceptionHandler {

    @Override
    public HttpResponse handle(HttpRequest request, ConstraintViolationException exception) {
        return return HttpResponse
                .badRequest();
    }
}


来源:https://stackoverflow.com/questions/56676486/constraintviolationexception-handler-isnt-executed-in-micronaut

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!