title: Zuul error filter: set response status dependent on error
body: <p>I am using <a href="https://github.com/Netflix/zuul" rel="nofollow noreferrer">Netflix Zuul v2.0</a> as an authentication proxy, i.e. I am using a "pre" filter to add a JWT token to the request header. </p>
  
  <p>The problem that I have is the following: when the request resource is not available an "Internal Server Error" (500) is returned instead of a "Request Timeout" (408) error. I have solved this by implementing a <a href="https://stackoverflow.com/questions/49000741/spring-cloud-zuul-custom-error-filter">custom error filter</a> and returning a 408 error whenever an error occurs.</p>
  
  <p>However, now I am returning a "Request Timeout" (408) error for every error, even when the cause was different. e.g. when there was a "bad request" or an "unauthorized" request. </p>
  
  <p>The question is: how do I know inside the error filter what the real cause of the problem was? e.g. I only want to return 408 when there really was a time out. Afaik the only information that I have is that there was an error, hence <code>ctx.getResponseStatusCode()</code> equals <code>500</code>. Or am I missing anything?</p>
  
  <p>Here is the implementation of the custom error filter:</p>
  
  <pre><code>@Component
  public class ConnectionErrorFilter extends ZuulFilter {
  
    protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran";
  
    @Override
    public String filterType() {
      return FilterConstants.ERROR_TYPE;
    }
  
    @Override
    public int filterOrder() {
      return FilterConstants.SEND_ERROR_FILTER_ORDER - 1; // Invoke before default error filter
    }
  
    @Override
    public boolean shouldFilter() {
      return true;
    }
  
    @Override
    public Object run() {
      RequestContext ctx = RequestContext.getCurrentContext();
      ctx.set(SEND_ERROR_FILTER_RAN); 
      ctx.setResponseStatusCode(408);  // Workaround because it is here IMO not detectable what the real cause was.
      // Thus, we assume that the cloud was not reachable.
      return null;
    }
  }
  </code></pre>