Притворное и необъявленное бросаемое исключение для 404 Not Found - PullRequest
1 голос
/ 13 марта 2019

Я пытаюсь перехватить ответ Feign и оценить исключение для ответа 404 Not Found, что-то похожее на шаблон REST, приведенный ниже:

try {
  response = restTemplate.exchange(url, HttpMethod.GET, request, Foo.class);

} catch (HttpClientErrorException ex) {
     if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
       throw ex;
     }
}

но для

Foo response = feignClient.getFoo(foo)

, который может бросить undeclaredThrowable с responseCode 404.

Ответы [ 3 ]

2 голосов
/ 14 марта 2019

Возможно, вы сможете использовать декодер ошибок и проверить код состояния 404.Например

public class MyErrorDecoder implements ErrorDecoder {

    @Override
    public Exception decode(String methodKey, Response response) {
        if (response.status() == 404) {
           ... 
           return new YourCustomException()

        }

        return errorStatus(methodKey, response);
    }
}

https://github.com/OpenFeign/feign/wiki/Custom-error-handling

1 голос
/ 13 марта 2019

Вы можете настроить контроллер ошибок cutom, который обрабатывает все ошибки приложения и возвращает желаемый тип сообщения. Я использую приведенную ниже реализацию с ResponseBody для веб-приложения. Настройте приведенную ниже реализацию в соответствии с вашими потребностями:

@Controller
public class CustomErrorController implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @ResponseBody
    @GetMapping("/error")
    public String handleError(HttpServletRequest request) {

        Enumeration<String> headerNames1 = request.getHeaderNames();
        Enumeration<String> headerNames2 = request.getHeaderNames();

        String headerJson = enumIterator(headerNames1, headerNames2, request);
        System.out.println(headerJson);

        Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);

        if (status != null) {
            Integer statusCode = Integer.valueOf(status.toString());

            if (statusCode == HttpStatus.NOT_FOUND.value()) {
                return "404 with other message";

            } else if (statusCode >= 500) {
                return "500  with other message";

            } else if (statusCode == HttpStatus.FORBIDDEN.value()) {
                return "403  with other message";
            }
        }
        return "miscellaneous error";
    }


    private String enumIterator(Enumeration<String> enumList1, Enumeration<String> enumList2, HttpServletRequest request) {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("{");
        boolean status = false;

        while (enumList1.hasMoreElements()) {

            if (status) {
                stringBuilder.append(",");
            }
            status = true;

            stringBuilder
                    .append("\"").append(enumList1.nextElement()).append("\"")
                    .append(":")
                    .append("\"").append(request.getHeader(enumList2.nextElement())).append("\"");
        }
        stringBuilder.append("}");

        return stringBuilder.toString();
    }
}

Или вы можете попробовать эту реализацию:

@Component
public class MyErrorController extends BasicErrorController {

    public MyErrorController(ErrorAttributes errorAttributes) {
        super(errorAttributes, new ErrorProperties());
    }

    @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE)
    public ResponseEntity<Map<String, Object>> xmlError(HttpServletRequest request) {

    // ...

    }
}
0 голосов
/ 14 марта 2019

В моем случае я решил следующее:

import java.lang.reflect.UndeclaredThrowableException;

    try {
      Foo response = feignClient.getFoo(foo)

    } catch (Exception ex) {
         if(((ServiceMethodException)((UndeclaredThrowableException) ex).getUndeclaredThrowable()).responseCode != 404){
           throw ex;
      }
    }

Идеальное решение предложено Вловато

...