Как определить статус ответа для обработчика исключений? - PullRequest
0 голосов
/ 01 октября 2018

Я использую обработчик исключений в своих контроллерах следующим образом:

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.CONFLICT)
@ResponseBody
public ApiError handleException(Exception e) {
    logger.error("Exception occurred {}", e.getMessage(), e);
    return new ApiError(HttpStatus.CONFLICT, e.getMessage());
}

Теперь я подумал о выборе правильного состояния ответа, зависит от типа исключения.Есть ли какое-либо отношение в лучших практиках?

Современный способ - везде использовать исключения Runtime, поэтому я не уверен, что всегда правильно использовать 4XX коды ответов для всех исключений Runtime.

Не могли бы вы уточнить?

PS

Я понимаю, что 4XX - ошибка клиента, а 5XX - ошибка сервера.

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Лично я просто выбрасываю пользовательское исключение обратно в контроллер, когда что-то идет не так во время выполнения, и автоматически создается ResponseEntity, возвращая мое исключение с кодом HttpStatus.Я стараюсь как можно чаще придерживаться логики и возвращать более понятный код вместе с сообщением и именем строки исключения.

Как: HttpStatus.PRECONDITION_FAILED, когда предварительная обработка не удалась (не из-за клиентаполезная нагрузка tho) HttpStatus.BAD_REQUEST, когда что-то не так в полезной нагрузке, полученной от клиента HttpStatus.NO_CONTENT, когда что-то в порядке, но мы возвращаем пустой ответ, потому что результат не найден и т. д. *

0 голосов
/ 01 октября 2018

Вы на правильном пути.На мой взгляд, не всегда правильно возвращать 4xx коды ответов для всех непроверенных исключений.Я бы предпочел сопоставить определенное подмножество этих исключений с 4xx кодами ответов, а все остальное должно быть внутренней ошибкой сервера, таким образом 500 код ответа.

@ResponseStatus(value=HttpStatus.NOT_FOUND)
public class EntityNotFoundException extends RuntimeException {
  // ...
}

Это исключение может быть выдано из @Service аннотированные классы, если сущность не найдена.Для других случаев вы также можете определить пользовательские исключения.Вы также можете придерживаться @ExceptionHandler, но тогда вам придется выполнять сопоставление самостоятельно.

Я бы рекомендовал сопоставлять исключения с соответствующими кодами ответов HTTP:

  • Неверный запрос: 400
  • Не найдено: 404
  • Запрещено: 403
  • Внутренняя ошибка сервера: 500

Кроме того, не забудьте вернуть один из следующих (или любых других) кодов ответов, если ваш запрос был успешным.

  • OK: 200
  • Создано: 201

Обычно используются вышеуказанные коды ответов.Конечно, их намного больше, но большинство API занимают лишь небольшое подмножество.При правильном сопоставлении клиентам легче узнать, что, возможно, пошло не так (или правильно), а затем они могут выполнить дальнейшие действия или отобразить необходимую клиенту информацию.Например:

  • 200: показать сообщение об успехе
  • 403: перенаправить на страницу входа
  • 400: показать ошибки, если формабыло отправлено

Хорошей практикой также является включение значимой информации в тело, если что-то пошло не так.Это также отвечает на вопрос: «Что мне делать, если я не могу сопоставить исключение с существующим кодом ответа?».Я задал себе тот же вопрос, и ответ прост.Попробуйте сопоставить его с ближайшим кодом ответа и включить в текст что-либо еще.

Если в клиенте отсутствует параметр, вы можете использовать следующее:

{ "error" : "Bad Request - Your request is missing parameter 'id'. Please verify and resubmit." }

Или для вышеуказанных ошибок в формах (код ответа 400):

{ 
    "errors": [
        "username": "AlreadyInUse",
    ]
}

Просто убедитесь, что вы придерживаетесь одного формата при возврате информации в теле.Иначе работать с болью.

0 голосов
/ 01 октября 2018

ИМХО, это просто не зависит от времени выполнения и проверенного шаблона исключений, но от семантически правильного дифференцирования.

  • Тип исключений не отражает эту семантику по умолчанию.
  • 5xx сообщает клиенту, что что-то пошло не так с вашей стороны.
  • 4xx сообщает клиенту, что API используется «неправильно» или нет ожидаемым образом.
  • Вы можете реализоватьКод состояния 4xx или 5xx с временем выполнения или проверенными исключениями.Это зависит только от вашей собственной архитектуры программного обеспечения.
  • Я бы не стал определять 4xx / 5xx из различий проверенных исключений или исключений времени выполнения (кажется, нарушает принцип наименьшего удивления - POLA )
...