简体   繁体   中英

Apache Camel onException Custom Error Handler is not working

I am new to apache camel features. So I have a problem with the DefaultErrorHandler in our project.

There are some errors in which we are not using any custom error handler. Whenever an exception occurs, apache camel logs it and this log level is ERROR . Apache camel is handling failure through DefaultErrorHandler which propagates exceptions back to the caller since there isn't any custom error handler.

This errors are like "User not found" so this shouldn't be a ERROR , this can be a WARN or INFO . Since we are not handling it, DefaultErrorHandler by Apache Camel handles it.

The error log like this on the server:

 main 2022-08-05 15:24:43.537 ERROR [user-manager] 1 --- [nio-8080-exec-5] o.a.c.p.e.DefaultErrorHandler            : Failed delivery for (MessageId:-0000000 on Exc │    │
│ main +[                                                                                                                                                                                                                                      │    │
│ main +[ Message History (complete message history is disabled)                                                                                                                                                                               │    │
│ main +[ ---------------------------------------------------------------------------------------------------------------------------------------                                                                                              │    │
│ main +[ RouteId              ProcessorId          Processor                                                                        Elapsed (ms)                                                                                              │    │
│ main +[ [PostUserToIdentity] [PostUserToIdentity] [from[direct://business.postUserToIdentity]                                    ] [        27]                                                                                              │    │
│ main +[     ...                                                                                                                                                                                                                              │    │
│ main +[ [PostUserToIdentity] [to58              ] [direct:postUserToIdentityRequestedInternal                                    ] [         0]                                                                                              │    │
│ main +[                                                                                                                                                                                                                                      │    │
│ main +[ Stacktrace                                                                                                                                                                                                                           │    │
│ main +[ ---------------------------------------------------------------------------------------------------------------------------------------                                                                                              │    │
│ main +[                                                                                                                                                                                                                                      │    │
│ main                                                                                                                                                                                                                                         │    │
│ main com.user.manager.exception.ConflictException: User already exists         

So, I wrote a Custom Handler and a RouteClass which extends the RouteBuilder with the proper Camel OnException clause.

OnConflictExceptionRoute Class

@Component
public class OnConflictExceptionRoute extends RouteBuilder {

    @Override
    public void configure() {
        log.info("Configuring extended create user by context route");

        onException(ConflictException.class)
            .process(new ConflictExceptionHandler())
            .handled(true);

        from("direct:business.postUserToIdentity")
            .routeId("PostUserToIdentity")
            .onException(ConflictException.class)
            .process(new ConflictExceptionHandler());
    }
}

Custom Error Handler

@Slf4j
public class ConflictExceptionHandler implements Processor {

    @Override
    public void process(Exchange exchange) {
        log.info("USER ALREADY EXISTS!");
        throw new ConflictException().withMessage("USER ALREADY EXISTS!");
    }
}

At the application startup, I could see that the Configure method in the RouteClass is triggered.

But when I am triggering the flow, I am still seeing the same error is handling by the DefaultErrorHandler.

Why it is not working? Is there any missing configuration? Thanks.

Camel has different exception handling behaviors. Route based: its handles for just this route in your example direct:business.postUserToIdentity route has a one route based exception handler and its overrides others. another one RouteBuilder based exception handler. its handles all routes in a routebuilder class. you have two definition. they have same onException. it is not logical. you can change like that your code.

 onException(ConflictException.class)
                .process(new ConflictExceptionHandler())
                .handled(true)
                .log("Exception handler works ${exception}");

        from("direct:business.postUserToIdentity")
                .routeId("PostUserToIdentity")
                .log("started")
                .throwException(new ConflictException());

So after a deep analysis, I found that I'd to resolve this issue with the service that we called in the application by extending the RouteBuilder class like this.

  @Override
    protected ErrorHandlerFactory createErrorHandlerBuilder() {
        DefaultErrorHandlerBuilder errorHandlerBuilder = super.defaultErrorHandler();
        // Changed from ERROR because it is expected that the service handles the exception.
        errorHandlerBuilder.setLevel(LoggingLevel.INFO.toString());
        RedeliveryPolicyDefinition policy = new RedeliveryPolicyDefinition();
        policy.setDisableRedelivery("false");
        policy.setRetriesExhaustedLogLevel(getRetriesExhaustedLogLevel().toString());
        errorHandlerBuilder.setRedeliveryPolicy(policy);
        return errorHandlerBuilder;
    }

Note: ExhaustedLogLevel is setted as DEBUG .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM