1

I want to add a custom error Zuul Filter and want to make sure SendErrorFilter does not execute. I have looked at few github links including Spring-cloud/spring-cloud-netflix and various stack-overflow questions:-

Customizing Zuul Exception

Overriding Zuul Filter SendErrorFilter

My code is as follows-

  public class CustomErrorFilter extends ZuulFilter {

private static final Logger LOG = LoggerFactory.getLogger(CustomErrorFilter.class);

@Override
public String filterType() {
    return "post";
}

@Override
public int filterOrder() {
    return -1; 
}

@Override
public boolean shouldFilter() {
    RequestContext ctx=RequestContext.getCurrentContext();
    if(ctx.getThrowable()!=null)
        return true;
    else
       return false;
}

@Override
public Object run() {

        RequestContext ctx = RequestContext.getCurrentContext();

            ctx.setThrowable(null); // response is not returned unless 
                                      throwable is set to null.
            ctx.remove("error.status_code");

            ctx.setResponseBody(“Error”);
            ctx.getResponse().setContentType("text/plain");
            ctx.setResponseStatusCode(400);

    }

    return null;
}

I am having the following issues-

  1. Setting filter order to -1 does not prohibit sendErrorFilter from running.

  2. To stop sendErrorFilter from running, I need to set zuul.SendErrorFilter.error.disable=true in bootstrap.yml

  3. To get a response body which is set in the custom error filter, i need to set throwable to null as mentioned in the github.

  4. Setting a filter as type "error" does nothing, and the custom filer does not run.

I would like someone to explain, what I am doing wrong and what is the most correct way of handling custom error filters, because there is lot of conflicting information available on the web.

Dependencies-

  1. spring cloud - Edgware.RELEASE

  2. spring cloud netflix starter zuul- 1.4.3.RELEASE

Prags
  • 2,457
  • 2
  • 21
  • 38
Indraneel Bende
  • 3,196
  • 4
  • 24
  • 36

1 Answers1

10

filtertype() should return "error" if you want to handle error scenario

filterOrder() should be -1 to execute before SendErrorFilter

Add the following lines to your filter(CustomErrorFilter )

protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";

and

@Override
public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    ctx.set(SEND_ERROR_FILTER_RAN);
    // rest of your code
    return null;
}

ctx.set(SEND_ERROR_FILTER_RAN); will block the SendErrorFilter from running.


Update:

Check shouldFilter() method in SendErrorFilter

@Override
public boolean shouldFilter() {
    RequestContext ctx = RequestContext.getCurrentContext();
    // only forward to errorPath if it hasn't been forwarded to already
    return ctx.getThrowable() != null
            && !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false);
}

For every request a RequestContext gets created, but spring is not setting SEND_ERROR_FILTER_RAN in the context. May be for older version you have to configure from yaml file (zuul.SendErrorFilter.error.disable=true) for newer version(1.4.3.RELEASE) its from code like ctx.set(SEND_ERROR_FILTER_RAN).

By default !ctx.getBoolean(SEND_ERROR_FILTER_RAN, false) this will evaluates to true and run() method of SendErrorFilter will execute.

if you put ctx.set(SEND_ERROR_FILTER_RAN) in your CustomErrorFilter with filterOrder() as -1, your CustomErrorFilter will execute first and we are setting the RequestContext with SEND_ERROR_FILTER_RAN as true. Now when it goes to shouldFilter() method of SendErrorFilter evaluate to false and it won't execute run() method of SendErrorFilter.

Pavan Kumar Jorrigala
  • 3,085
  • 16
  • 27