Глобальная обработка ошибок с использованием Spring boot + WebFlux - PullRequest
0 голосов
/ 26 июня 2019

Я задаю себе вопрос, как мы можем обрабатывать исключения глобально при использовании реактивного программирования в Spring boot rest rest.

Я бы предположил, что @ControllerAdvice не будет работать, потому что я пробовал это, и это было неудачно.

Моя вторая попытка в настоящее время это опция: Использование пользовательских атрибутов:

@Component
public class OsvcErrorAttributes extends DefaultErrorAttributes {

public OsvcErrorAttributes() {
    super(true);
}

@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
    return assembleError(request);
}

private Map<String, Object> assembleError(ServerRequest request) {
    ServerException serverException = (ServerException)getError(request);

    Map<String, Object> errorAttributes = new HashMap<>();
    errorAttributes.put("message", serverException.getMessage());
    errorAttributes.put("errors", serverException.getErrorMap());
    return errorAttributes;
}

}

и WebExceptionHandler, как это:

@Component
@Order(-2)
public class OsvcErrorHandler extends AbstractErrorWebExceptionHandler {
public OsvcErrorHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
                        ApplicationContext applicationContext) {
    super(errorAttributes, resourceProperties, applicationContext);

    // TODO: 25.06.2019 temporary workaround
    ServerCodecConfigurer serverCodecConfigurer = new DefaultServerCodecConfigurer();
    setMessageWriters(serverCodecConfigurer.getWriters());
    setMessageReaders(serverCodecConfigurer.getReaders());
}

@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
    return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}

private Mono<ServerResponse> renderErrorResponse(ServerRequest serverRequest) {

    final Map<String, Object> errorAttributes = getErrorAttributes(serverRequest, true);
    return ServerResponse.status(HttpStatus.BAD_REQUEST)
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .body(BodyInserters.fromObject(errorAttributes));
}

}

Код, выдающий ошибку:

@Data
@Service
public class ContactService {

private final ContactRepository contactRepository;

public Mono<Business> saveNewContact(Business business) {
    return contactRepository.save(business)
            .onErrorMap(throwable ->
                ServerException.create(throwable.getMessage())
                    .persistError("ico", business.getIco(), "ICO is probably duplicate"));
}

}

Проблема в том, что это тоже не работает. Я следовал этому уроку и не могу понять, не прав ли я с чем-то или нет. Любая помощь или решение приветствуется. Спасибо

Ответы [ 2 ]

0 голосов
/ 21 июля 2019

Вы просто используете ServerCodecConfigurer-инъекцию в своем конструкторе глобального обработчика ошибок, как этот.

public OsvcErrorHandler(GlobalErrorAttributes errorAttributes, ApplicationContext applicationContext, 
                ServerCodecConfigurer serverCodecConfigurer) {
   super(errorAttributes, new ResourceProperties(), applicationContext);
   super.setMessageWriters(serverCodecConfigurer.getWriters());
   super.setMessageReaders(serverCodecConfigurer.getReaders());
}

Пожалуйста, найдите пример кода в репозитории git .

0 голосов
/ 02 июля 2019

Попробуйте ввести ServerCodecConfigurer вместо того, чтобы создавать его. Я также добавляю ViewResolversProvider при этом, хотя это может и не понадобиться.

    public OsvcErrorHandler(
            final CustomErrorAttributes customAttributes,
            final ResourceProperties resourceProperties,
            final ObjectProvider<List<ViewResolver>> viewResolversProvider,
            final ServerCodecConfigurer serverCodecConfigurer,
            final ApplicationContext applicationContext
    ) {
        super(customAttributes, resourceProperties, applicationContext);

        this.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
        this.setMessageWriters(serverCodecConfigurer.getWriters());
        this.setMessageReaders(serverCodecConfigurer.getReaders());
    }
...