Nirmal
Nirmal

Reputation: 559

NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.web.reactive.error.ErrorAttributes' available:

I'm following https://www.baeldung.com/spring-webflux-errors tutorial to handle errors in Spring Webflux project.

package com.example.demo.exception;

import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.reactive.error.ErrorAttributes;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;

import java.util.Map;

@Component
@Order(-2)
public class ExceptionWebHandler extends AbstractErrorWebExceptionHandler {

    public ExceptionWebHandler(ErrorAttributes errorAttributes,
                               ApplicationContext applicationContext,
                               ServerCodecConfigurer serverCodecConfigurer) {
        super(errorAttributes, new ResourceProperties(), applicationContext);
        super.setMessageWriters(serverCodecConfigurer.getWriters());
        super.setMessageReaders(serverCodecConfigurer.getReaders());
    }
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(final ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    private Mono<ServerResponse> renderErrorResponse(ServerRequest serverRequest) {
        Map<String,Object> errorAttributes = getErrorAttributes(serverRequest, false);
        return ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromObject(errorAttributes.get("message")));
    }
}

I'm getting the following error when running the project.

Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.web.reactive.error.ErrorAttributes' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Description:

Parameter 0 of constructor in com.example.demo.exception.ExceptionWebHandler required a bean of type 'org.springframework.boot.web.reactive.error.ErrorAttributes' that could not be found.

The following candidates were found but could not be injected: - Bean method 'errorAttributes' in 'ErrorWebFluxAutoConfiguration' not loaded because not a reactive web application

Action:

Consider revisiting the entries above or defining a bean of type 'org.springframework.boot.web.reactive.error.ErrorAttributes' in your configuration.

I'm not sure which object should I autowire. The error message says its for ErrorAttributes, but I dont know how. I tried adding @Autowired to the parameter in the constructor and separately as a property of the class, but it didn't help.

Upvotes: 4

Views: 8676

Answers (1)

Toerktumlare
Toerktumlare

Reputation: 14712

The following candidates were found but could not be injected: - Bean method 'errorAttributes' in 'ErrorWebFluxAutoConfiguration' not loaded because not a reactive web application

is probably your problem or at least one of the problems.

The Spring documentation states in the last paragraph:

Adding both spring-boot-starter-web and spring-boot-starter-webflux modules in your application results in Spring Boot auto-configuring Spring MVC, not WebFlux. This behavior has been chosen because many Spring developers add spring-boot-starter-webflux to their Spring MVC application to use the reactive WebClient. You can still enforce your choice by setting the chosen application type to SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE).

So somewhere in your application you are pulling in spring-web either directly or transitively through some other dependency.

This in turn will result in that your application will automatically be configured as a non-webflux application.

Upvotes: 7

Related Questions