簡體   English   中英

如何在 Spring 啟動 GraphQL 中實現 javax.validation.ConstraintViolationException 的異常處理程序?

[英]How to implement exception handler for javax.validation.ConstraintViolationException in Spring boot GraphQL?

如何在 Spring 啟動 GraphQL 中實現javax.validation.ConstraintViolationException的異常處理程序?

我收到以下回復

{
"errors": [
    {
        "message": "INTERNAL_ERROR for a7027473-59c3-b9ad-1917-873f354a352d",
        "locations": [
            {
                "line": 2,
                "column": 5
            }
        ],
        "path": [
            "createAuction"
        ],
        "extensions": {
            "classification": "INTERNAL_ERROR"
        }
    }
],
"data": {
    "createAuction": null
}

}

以及日志中的以下異常

javax.validation.ConstraintViolationException: createAuction.auctionInput.startTime: Auction start date time must be greater than the current date time
    at org.springframework.graphql.data.method.annotation.support.HandlerMethodInputValidator.validate(HandlerMethodInputValidator.java:80) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.graphql.data.method.annotation.support.DataFetcherHandlerMethod.validateAndInvoke(DataFetcherHandlerMethod.java:189) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.graphql.data.method.annotation.support.DataFetcherHandlerMethod.invoke(DataFetcherHandlerMethod.java:122) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.graphql.data.method.annotation.support.AnnotatedControllerConfigurer$SchemaMappingDataFetcher.get(AnnotatedControllerConfigurer.java:514) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.graphql.execution.ContextDataFetcherDecorator.lambda$get$0(ContextDataFetcherDecorator.java:74) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.graphql.execution.ReactorContextManager.invokeCallable(ReactorContextManager.java:104) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.graphql.execution.ContextDataFetcherDecorator.get(ContextDataFetcherDecorator.java:73) ~[spring-graphql-1.0.1.jar:1.0.1]
    at org.springframework.boot.actuate.metrics.graphql.GraphQlMetricsInstrumentation.lambda$instrumentDataFetcher$1(GraphQlMetricsInstrumentation.java:98) ~[spring-boot-actuator-2.7.2.jar:2.7.2]
    at graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation.lambda$instrumentDataFetcher$0(DataLoaderDispatcherInstrumentation.java:87) ~[graphql-java-18.2.jar:na]
    at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:279) ~[graphql-java-18.2.jar:na]
    at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:210) ~[graphql-java-18.2.jar:na]
    at graphql.execution.ExecutionStrategy.resolveField(ExecutionStrategy.java:182) ~[graphql-java-18.2.jar:na]
    at graphql.execution.AsyncSerialExecutionStrategy.lambda$execute$1(AsyncSerialExecutionStrategy.java:43) ~[graphql-java-18.2.jar:na]
    at graphql.execution.Async.eachSequentiallyImpl(Async.java:80) ~[graphql-java-18.2.jar:na]
    at graphql.execution.Async.eachSequentially(Async.java:69) ~[graphql-java-18.2.jar:na]
    at graphql.execution.AsyncSerialExecutionStrategy.execute(AsyncSerialExecutionStrategy.java:38) ~[graphql-java-18.2.jar:na]
    at graphql.execution.Execution.executeOperation(Execution.java:159) ~[graphql-java-18.2.jar:na]
    at graphql.execution.Execution.execute(Execution.java:105) ~[graphql-java-18.2.jar:na]
    at graphql.GraphQL.execute(GraphQL.java:641) ~[graphql-java-18.2.jar:na]

您必須使用 @RestControllerAdvice 注釋為您的 rest controller 創建建議,這將捕獲您的異常,然后您可以處理此建議中的所有異常。 這是示例

@RestControllerAdvice
public class ProductExceptionHandler {

@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<ErrorMessage> handleInvalidArgument(ConstraintViolationException ex, WebRequest webRequest) {
    return generateErrorMessage(ex, webRequest);
}

private ResponseEntity<ErrorMessage> generateErrorMessage(Throwable ex, WebRequest request){
    ErrorMessage errorMessage = new ErrorMessage.ErrorMessageBuilder()
            .statusCode(HttpStatus.BAD_REQUEST.value())
            .timeStamp(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").format(LocalDateTime.now()))
            .message(ex.getMessage())
            .description(request.getDescription(false))
            .build();
    return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);
}

}

需要擴展DataFetcherExceptionResolverAdapter並且此 class 必須由您的 controller 擴展。

public class CustomExceptionResolver extends DataFetcherExceptionResolverAdapter {

protected Logger logger = LoggerFactory.getLogger(this.getClass());

@Override
protected GraphQLError resolveToSingleError(Throwable ex, DataFetchingEnvironment env) {
    Throwable t = NestedExceptionUtils.getMostSpecificCause(ex);
    logger.debug("Custom Exception {}", t.getLocalizedMessage());
    // Spring & custom validation error 
    if (ex instanceof ConstraintViolationException constraintViolationException) {
        ValidationErrorResponse error = new ValidationErrorResponse();
        for (ConstraintViolation<?> violation : constraintViolationException.getConstraintViolations()) {
            error.getViolations().add(new Violation(violation.getPropertyPath().toString(), violation.getMessage()));
        }
        return GraphqlErrorBuilder.newError(env)
                .errorType(ErrorType.ValidationError).message(error.getMessage()).build();
    } else {
            return GraphqlErrorBuilder.newError(env)
                    .errorType(AuctionErrorType.OperationNotSupported).message(illegalStateException.getLocalizedMessage()).build();
        }
    }
    
    return null;
}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM