Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ReasonInvalidResourceID — sync-формат: malformed own-id, отвергнутый // первым стейтментом RPC. ReasonInvalidResourceID = Reason{/* contains filtered or unexported fields */} // ReasonResourceNotFound — direct-read: own-owned id корректен, строки в // своей БД нет. ReasonResourceNotFound = Reason{/* contains filtered or unexported fields */} // ReasonPeerResourceMissing — peer-validate: чужой id не существует у // владельца. Код — FAILED_PRECONDITION: консумер здесь не «не нашёл своё», // а «предусловие на чужой ресурс не выполнено». ReasonPeerResourceMissing = Reason{/* contains filtered or unexported fields */} // ReasonPeerResourceState — peer-validate: чужой ресурс есть, состояние не // позволяет. ReasonPeerResourceState = Reason{/* contains filtered or unexported fields */} // для мутаций — непроверяемое предусловие не считается выполненным. ReasonPeerUnavailable = Reason{/* contains filtered or unexported fields */} )
Пять полос закрытого словаря. Шестой нет и не может быть заведена снаружи; добавление шестой здесь роняет TestLaneDictionaryIsClosedAtFive, который требует объявить её контрактом, а не просто вписать значение.
Каждое значение — конструктор ошибок своей полосы: `ReasonX.Errf(...)`. Отдельных функций-конструкторов на полосу нет намеренно — три из пяти полос сегодня не имеют производителя в дереве, и такие функции были бы мёртвым кодом (ban #11), тогда как сам ЗАКРЫТЫЙ НАБОР мёртвым не бывает: он и есть то, что запрещает шестую.
#nosec G101 -- ВСЕ ПЯТЬ токенов ниже суть МАШИННЫЙ ПРИЗНАК ПОЛОСЫ ОТКАЗА, уезжающий клиенту в деталях ответа, а не секрет. Эвристика статического анализа ключуется на форме имени — заглавные с подчёркиваниями рядом со строковым литералом — и не различает токен публичного контракта от учётных данных. Обоснование стоит здесь, у ГРУППЫ, а не построчно: предмет у всех пяти один, и построчные пометки закрывали бы по одной, оставляя следующую находкой при каждом добавлении полосы.
Functions ¶
This section is empty.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder — строитель gRPC-статуса с деталями.
func FailedPrecondition ¶
FailedPrecondition создает ошибку 400 (предусловие не выполнено).
func InvalidArgument ¶
func InvalidArgument() *Builder
InvalidArgument создает ошибку 400, к которой можно добавить FieldViolation.
func NotFound ¶
NotFound создает ошибку 404 с ResourceInfo detail.
Текст сообщения: `<Kind> '<id>' was not found`. Используется resource-manager (Cloud, Folder, Organization).
func (*Builder) AddFieldViolation ¶
AddFieldViolation добавляет нарушение поля к BadRequest details.
func (*Builder) Err ¶
Err собирает итоговую ошибку с деталями (BadRequest, опционально LocalizedMessage).
LocalizedMessage добавляется ТОЛЬКО если был вызван WithLocale("<locale>") с непустым locale. По умолчанию Kachō возвращает только BadRequest — осознанное решение (более structured, machine-readable).
func (*Builder) WithLocale ¶
WithLocale устанавливает locale для LocalizedMessage detail. При Err() добавится detail вида:
{ "@type": "type.googleapis.com/google.rpc.LocalizedMessage", "locale": "<locale>", "message": "<status.message>" }
Если locale пустой — LocalizedMessage не добавляется.
type PeerRef ¶
PeerRef — координата ресурса, о котором отказ.
Service — имя сервиса-источника отказа («vpc»), из которого собирается ErrorInfo.domain вида "<service>.kacho.cloud".
ResourceID пуст там, где полоса намеренно не подтверждает существование чужого ресурса (анти-oracle). Пустое значение НЕ едет в метаданные пустой строкой: ключ с пустым значением читается как «идентификатор известен и пуст», то есть сообщает ровно то, что скрытие и должно было закрыть.
type Reason ¶
type Reason struct {
// contains filtered or unexported fields
}
Reason — машинный признак полосы резолва, по которому клиент отличает «я не нашёл СВОЁ» от «предусловие на ЧУЖОЙ ресурс не выполнено», не разбирая прозу сообщения (api-conventions.md §By-lane code-split).
Почему тип, а не строка ¶
Токен, переданный строкой, выразим любой: шестая полоса заводится опечаткой и доезжает до клиента молча, потому что клиент ключуется на равенство и просто не совпадёт — то есть отказ будет выглядеть как отсутствие признака. Поля здесь неэкспортируемые, поэтому за пределами пакета собрать значение с произвольным токеном НЕЛЬЗЯ: словарь закрыт компилятором, а не соглашением.
Почему код лежит ВНУТРИ полосы ¶
Токен и код — две половины одного утверждения о полосе. Разъехавшись, они дают худший из возможных исходов: ответ, который машинно заявляет одну полосу, а кодом — другую. Держать их вместе значит сделать расхождение невыразимым, а не обнаруживаемым. Отсюда же следует, что смена канона полосы — правка ОДНОЙ строки здесь, а не тринадцати мест в сервисах.
func AllReasons ¶
func AllReasons() []Reason
AllReasons возвращает словарь полос целиком. Нужен проверкам, утверждающим свойство НАБОРА (закрытость, отсутствие дублей), — без него они перечисляли бы полосы вручную и молчали бы ровно о той, которую забыли дописать.
func (Reason) Errf ¶
Errf собирает отказ этой полосы: код берётся у полосы, проза — у вызывающего, машинный признак уезжает в details.
Проза НЕ выводится из полосы и не дополняется ею. Тексты — часть контракта Kachō и принадлежат вызывающему; полоса добавляет к сказанному только машинный признак, по которому клиент отличает «повтори позже» от «исправь ввод», не парся сообщение. Детали не влияют на HTTP-статус края (grpc-gateway отображает по КОДУ), поэтому постановка признака ничего не ломает у REST-клиента.
Необъявленная полоса (нулевое значение) отдаёт INTERNAL без деталей: отказ, у которого нет полосы, не вправе притвориться полосой контракта.
func (Reason) IsDeclared ¶
IsDeclared отличает полосу словаря от нулевого значения типа. Нулевое значение собрать можно (`var r Reason`) — Go этого не запрещает; значимо то, что оно НЕ выдаёт себя за полосу контракта.