@Override
 public void notify(ZuulFilter filter, ExecutionStatus status) {
   DynamicCounter.increment(
       METRIC_PREFIX + filter.getClass().getSimpleName(),
       "status",
       status.name(),
       "filtertype",
       filter.filterType());
 }
    @Test
    public void testProcessZuulFilterException() {
      FilterProcessor processor = new FilterProcessor();
      processor = spy(processor);

      try {
        ZuulFilterResult r = new ZuulFilterResult(ExecutionStatus.FAILED);
        r.setException(new Exception("Test"));
        when(filter.runFilter()).thenReturn(r);
        when(filter.filterType()).thenReturn("post");
        processor.processZuulFilter(filter);
        assertFalse(true);
      } catch (Throwable e) {
        assertEquals(e.getCause().getMessage(), "Test");
      }
    }
    @Test
    public void testErrorException() {
      FilterProcessor processor = new FilterProcessor();
      processor = spy(processor);

      try {
        when(processor.runFilters("error")).thenThrow(new Exception("test"));
        when(filter.filterType()).thenReturn("post");
        processor.error();
        assertTrue(true);
      } catch (Throwable e) {
        assertFalse(true);
      }
    }
    @Test
    public void testErrorHttpException() {
      HttpServletRequest request = mock(HttpServletRequest.class);
      HttpServletResponse response = mock(HttpServletResponse.class);
      RequestContext.getCurrentContext().setRequest(request);
      RequestContext.getCurrentContext().setResponse(response);

      FilterProcessor processor = new FilterProcessor();
      processor = spy(processor);
      try {
        when(processor.runFilters("error")).thenThrow(new ZuulException("test", 400, "test"));
        when(filter.filterType()).thenReturn("post");
        processor.error();
        assertTrue(true);
      } catch (Throwable e) {
        e.printStackTrace();
        assertFalse(true);
      }
    }
    @Test
    public void testPostProcessHttpException() {
      HttpServletRequest request = mock(HttpServletRequest.class);
      HttpServletResponse response = mock(HttpServletResponse.class);
      RequestContext.getCurrentContext().setRequest(request);
      RequestContext.getCurrentContext().setResponse(response);

      FilterProcessor processor = new FilterProcessor();
      processor = spy(processor);
      try {
        when(processor.runFilters("post")).thenThrow(new ZuulException("test", 400, "test"));
        when(filter.filterType()).thenReturn("post");
        processor.postRoute();
      } catch (ZuulException e) {
        assertEquals(e.getMessage(), "test");
        assertEquals(e.nStatusCode, 400);
      } catch (Throwable e) {
        e.printStackTrace();
        assertFalse(true);
      }
    }
  /**
   * Processes an individual ZuulFilter. This method adds Debug information. Any uncaught Thowables
   * are caught by this method and converted to a ZuulException with a 500 status code.
   *
   * @param filter
   * @return the return value for that filter
   * @throws ZuulException
   */
  public Object processZuulFilter(ZuulFilter filter) throws ZuulException {

    RequestContext ctx = RequestContext.getCurrentContext();
    boolean bDebug = ctx.debugRouting();
    final String metricPrefix = "zuul.filter-";
    long execTime = 0;
    String filterName = "";
    try {
      long ltime = System.currentTimeMillis();
      filterName = filter.getClass().getSimpleName();

      RequestContext copy = null;
      Object o = null;
      Throwable t = null;

      if (bDebug) {
        Debug.addRoutingDebug(
            "Filter " + filter.filterType() + " " + filter.filterOrder() + " " + filterName);
        copy = ctx.copy();
      }

      ZuulFilterResult result = filter.runFilter();
      ExecutionStatus s = result.getStatus();
      execTime = System.currentTimeMillis() - ltime;

      switch (s) {
        case FAILED:
          t = result.getException();
          ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);
          break;
        case SUCCESS:
          o = result.getResult();
          ctx.addFilterExecutionSummary(filterName, ExecutionStatus.SUCCESS.name(), execTime);
          if (bDebug) {
            Debug.addRoutingDebug(
                "Filter {"
                    + filterName
                    + " TYPE:"
                    + filter.filterType()
                    + " ORDER:"
                    + filter.filterOrder()
                    + "} Execution time = "
                    + execTime
                    + "ms");
            Debug.compareContextState(filterName, copy);
          }
          break;
        default:
          break;
      }

      if (t != null) throw t;

      usageNotifier.notify(filter, s);
      return o;

    } catch (Throwable e) {
      if (bDebug) {
        Debug.addRoutingDebug(
            "Running Filter failed "
                + filterName
                + " type:"
                + filter.filterType()
                + " order:"
                + filter.filterOrder()
                + " "
                + e.getMessage());
      }
      usageNotifier.notify(filter, ExecutionStatus.FAILED);
      if (e instanceof ZuulException) {
        throw (ZuulException) e;
      } else {
        ZuulException ex =
            new ZuulException(
                e, "Filter threw Exception", 500, filter.filterType() + ":" + filterName);
        ctx.addFilterExecutionSummary(filterName, ExecutionStatus.FAILED.name(), execTime);
        throw ex;
      }
    }
  }