Search code examples
resthttprequestinterceptorballerina

How can I prevent ResponseInterceptors from executing when using a RequestErrorInterceptor in Ballerina?


I'm looking to implement a RequestErrorInterceptor to handle errors occurring in Ballerina HTTP request interceptors.

Within this error interceptor, I aim to generate an error response message and prevent any further processing. Here's the RequestErrorInterceptor code I've written:

public isolated service class FhirRequestErrorInterceptor {
    http:RequestErrorInterceptor;

    resource isolated function 'default [string... path](http:RequestContext ctx, http:Caller caller, 
                                                        http:Request req, error err) returns http:InternalServerError {
        log:printError("HIT FhirRequestErrorInterceptor");
        http:InternalServerError errorResponse = {
            body: "FhirRequestErrorInterceptor response"
        };

        return errorResponse;
    }
}

However, I've noticed that ResponseInterceptors are also being executed. How can I achieve my requirement without invoking Response interceptors?


Solution

  • The order of execution in Ballerina depends on how you've configured the interceptor pipeline. If you return a valid HTTP response from your fhirRequestErrorInterceptor, it will trigger any subsequent response interceptors in the pipeline.

    Consider the following pipeline setup as an example:

    interceptors: [RequestInterceptor, ResponseInterceptor1, RequestErrorInterceptor, ResponseInterceptor2]

    In this setup, if your RequestInterceptor returns an error and your RequestErrorInterceptor returns an HTTP response, the following sequence of events will occur:

    1. The request passes through the RequestInterceptor, resulting in an error.
    2. The error is intercepted by the RequestErrorInterceptor, which generates a valid HTTP response.
    3. As a valid response is returned, the control shifts to the response flow, and any response interceptors downstream in the pipeline are triggered.
    4. Consequently, the response will be processed by ResponseInterceptor1.

    If we want to prevent ResponseInterceptor1 from being executed in this scenario, you can simply rearrange the interceptor pipeline by placing ResponseInterceptor1 after RequestErrorInterceptor, like this:

    interceptors: [RequestInterceptor, RequestErrorInterceptor, ResponseInterceptor1, ResponseInterceptor2]

    This adjustment in the pipeline order will ensure that ResponseInterceptor1 is only triggered when a valid request passes through and is not invoked when the RequestErrorInterceptor handles errors.