Repository: micronaut-projects/micronaut-core
File: http-server/src/main/java/io/micronaut/http/server/RequestLifecycle.java (Java)

Code before:
        try {
            return runWithFilters(request, (filteredRequest, propagatedContext) -> onErrorNoFilter(filteredRequest, throwable, propagatedContext))
                .onErrorResume(t -> createDefaultErrorResponseFlow(request, t));
        } catch (Throwable e) {
            return createDefaultErrorResponseFlow(request, e);
        }
    }

    private ExecutionFlow<HttpResponse<?>> onErrorNoFilter(HttpRequest<?> request, Throwable t, PropagatedContext propagatedContext) {
        // find the origination of the route
        Optional<RouteInfo> previousRequestRouteInfo = request.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class);
        Class<?> declaringType = previousRequestRouteInfo.map(RouteInfo::getDeclaringType).orElse(null);

        if ((t instanceof CompletionException || t instanceof ExecutionException) && t.getCause() != null) {
            // top level exceptions returned by CompletableFutures. These always wrap the real exception thrown.
            t = t.getCause();
        }
        if (t instanceof ConversionErrorException cee && cee.getCause() instanceof JsonSyntaxException jse) {
            // with delayed parsing, json syntax errors show up as conversion errors
            t = jse;
        }
        final Throwable cause = t;

        RouteMatch<?> errorRoute = routeExecutor.findErrorRoute(cause, declaringType, request);
        if (errorRoute != null) {
            request.setAttribute(HttpAttributes.ROUTE_INFO, errorRoute);
            if (routeExecutor.serverConfiguration.isLogHandledExceptions()) {
                routeExecutor.logException(cause);
            }
            try {
                return ExecutionFlow.just(errorRoute)
                    .flatMap(routeMatch -> routeExecutor.callRoute(propagatedContext, routeMatch, request)
                        .flatMap(res -> handleStatusException(request, res, routeMatch, propagatedContext))
                    )
                    .onErrorResume(u -> createDefaultErrorResponseFlow(request, u))
                    .<HttpResponse<?>>map(response -> {
                        response.setAttribute(HttpAttributes.EXCEPTION, cause);
                        return response;
                    })
                    .onErrorResume(throwable -> createDefaultErrorResponseFlow(request, throwable));
            } catch (Throwable e) {
                return createDefaultErrorResponseFlow(request, e);
            }
        } else {
            Optional<BeanDefinition<ExceptionHandler>> optionalDefinition = routeExecutor.beanContext.findBeanDefinition(ExceptionHandler.class, Qualifiers.byTypeArgumentsClosest(cause.getClass(), Object.class));
            if (optionalDefinition.isPresent()) {
                BeanDefinition<ExceptionHandler> handlerDefinition = optionalDefinition.get();
                final Optional<ExecutableMethod<ExceptionHandler, Object>> optionalMethod = handlerDefinition.findPossibleMethods("handle").findFirst();
                RouteInfo<Object> routeInfo;
                if (optionalMethod.isPresent()) {
                    routeInfo = new ExecutableRouteInfo<>(optionalMethod.get(), true);

Review comment (suggestion):
Look like we forgot to change the route info for error an status routes

Code after:
        try {
            return runWithFilters(request, (filteredRequest, propagatedContext) -> onErrorNoFilter(filteredRequest, throwable, propagatedContext))
                .onErrorResume(t -> createDefaultErrorResponseFlow(request, t));
        } catch (Throwable e) {
            return createDefaultErrorResponseFlow(request, e);
        }
    }

    private ExecutionFlow<HttpResponse<?>> onErrorNoFilter(HttpRequest<?> request, Throwable t, PropagatedContext propagatedContext) {
        // find the origination of the route
        Optional<RouteInfo> previousRequestRouteInfo = request.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class);
        Class<?> declaringType = previousRequestRouteInfo.map(RouteInfo::getDeclaringType).orElse(null);

        if ((t instanceof CompletionException || t instanceof ExecutionException) && t.getCause() != null) {
            // top level exceptions returned by CompletableFutures. These always wrap the real exception thrown.
            t = t.getCause();
        }
        if (t instanceof ConversionErrorException cee && cee.getCause() instanceof JsonSyntaxException jse) {
            // with delayed parsing, json syntax errors show up as conversion errors
            t = jse;
        }
        final Throwable cause = t;

        RouteMatch<?> errorRoute = routeExecutor.findErrorRoute(cause, declaringType, request);
        if (errorRoute != null) {
            RouteExecutor.setRouteAttributes(request, errorRoute);
            if (routeExecutor.serverConfiguration.isLogHandledExceptions()) {
                routeExecutor.logException(cause);
            }
            try {
                return ExecutionFlow.just(errorRoute)
                    .flatMap(routeMatch -> routeExecutor.callRoute(propagatedContext, routeMatch, request)
                        .flatMap(res -> handleStatusException(request, res, routeMatch, propagatedContext))
                    )
                    .onErrorResume(u -> createDefaultErrorResponseFlow(request, u))
                    .<HttpResponse<?>>map(response -> {
                        response.setAttribute(HttpAttributes.EXCEPTION, cause);
                        return response;
                    })
                    .onErrorResume(throwable -> createDefaultErrorResponseFlow(request, throwable));
            } catch (Throwable e) {
                return createDefaultErrorResponseFlow(request, e);
            }
        } else {
            Optional<BeanDefinition<ExceptionHandler>> optionalDefinition = routeExecutor.beanContext.findBeanDefinition(ExceptionHandler.class, Qualifiers.byTypeArgumentsClosest(cause.getClass(), Object.class));
            if (optionalDefinition.isPresent()) {
                BeanDefinition<ExceptionHandler> handlerDefinition = optionalDefinition.get();
                final Optional<ExecutableMethod<ExceptionHandler, Object>> optionalMethod = handlerDefinition.findPossibleMethods("handle").findFirst();
                RouteInfo<Object> routeInfo;
                if (optionalMethod.isPresent()) {
                    routeInfo = new ExecutableRouteInfo<>(optionalMethod.get(), true);