У меня есть бэкэнд-проект, в котором существует собственное «родительское исключение», что-то вроде этого (также у меня есть InvalidArgumentException, полученное из этого исключения):
class CaliException extends \Exception {
private $caliCode;
public function __construct(string $message = "", string $caliCode = self::UNDEFINED_CODE,
int $code = 0, Throwable $previous = null) {
parent::__construct($message, $code, $previous);
$this->caliCode = $caliCode;
}
function getCaliCode(): string {
return $this->caliCode;
}
}
Это ясно из кода выше, эта цель пользовательского класса заключается в способности хранить строковые коды. Зачем мне нужны строковые коды? Потому что у меня есть HTTP API, который работает следующим образом:
- Получить JSON запрос
- Сделать что-то
- Создать JSON вывод с полем 'state' который содержит либо код сгенерированного исключения, либо ответ «200». Эти коды состояния очень полезны для клиента, который может различать guish различных проблем и реагировать на них соответственно.
Так что есть проблема. Приведенная выше система создает код, подобный следующему:
class UsernameFormatException extends InvalidArgumentException {
public const USERNAME_FORMAT_UNDEFINED_CODE = "DM:USERCA:0001";
public function __construct(string $message = "", string $calistoCode = self::USERNAME_FORMAT_UNDEFINED_CODE,
int $code = 0, \Throwable $previous = null) {
parent::__construct($message, $calistoCode, $code, $previous);
}
}
class PasswordFormatException extends InvalidArgumentException {
public const PASSWORD_FORMAT_UNDEFINED_CODE = "DM:USERCA:0002";
public function __construct(string $message = "", string $calistoCode = self::PASSWORD_FORMAT_UNDEFINED_CODE,
int $code = 0, \Throwable $previous = null) {
parent::__construct($message, $calistoCode, $code, $previous);
}
}
class InvalidLastActivityTimestampException extends InvalidArgumentException {
public const INVALID_TIMESTAMP = "DM:USERCA:0003";
public function __construct(string $message = "", string $calistoCode = self::INVALID_TIMESTAMP,
int $code = 0, \Throwable $previous = null) {
parent::__construct($message, $calistoCode, $code, $previous);
}
}
class InvalidCreationTimestampException extends InvalidArgumentException {
public const INVALID_TIMESTAMP = "DM:USERCA:0004";
public function __construct(string $message = "", string $calistoCode = self::INVALID_TIMESTAMP,
int $code = 0, \Throwable $previous = null) {
parent::__construct($message, $calistoCode, $code, $previous);
}
}
Как видно, для каждого случая недопустимого аргумента я создаю новое CaliException
полученное исключение . Я считаю это не круто. Это хорошо? Как я могу улучшить код?
Бонусный вопрос: я прочитал, что должен выбросить \InvalidArgumentException
, когда это ошибка программиста, поэтому исключение не должно быть поймано. Но в моем коде нет \InvalidArgumentException
только моей собственной версии этого. Является ли это приемлемым в контексте лучших практик и т. Д.? И как отличить guish, когда это ошибка программиста и когда это ошибка пользователя (неверный ввод пользователя)? (В конце концов, любые недопустимые значения, переданные функции, являются недопустимыми входные данные относительно этой функции)