Error Taxonomy (classes, severity, retryability)
Vocabulário canônico de erros da Koder Stack: o enum fechado de CLASSES (categorias funcionais — `DL`, `UP`, `AU`, `NW`, `DB`, `UI`, `IO`, `PM`, `VL`, `XX`), a definição semântica + regra de desempate de cada classe, a escala de SEVERIDADE (`fatal`/`error`/`warning`/`info`) e a classificação de RETRYABILITY. É a fonte de verdade dos campos `error_category` e `severity` que `specs/errors/reporting.kmd` (Group D) captura e que o Error ID de `specs/errors/user-facing-messages.kmd §4` encurta. Não define texto exibido (user-facing-messages), captura/telemetria (reporting), padrões de código (code/error-handling) nem o envelope de wire (model).
Define o vocabulário dos erros (classes, severidade, retryability). O shape máquina-legível é
specs/errors/model.kmd; o texto humano éspecs/errors/user-facing-messages.kmd; a captura/telemetria éspecs/errors/reporting.kmd; os padrões de código sãospecs/code/error-handling.kmd. Esta spec é a fonte única dos camposerror_categoryeseverityque aqueles documentos consomem.
Applicability
Toda superfície Koder que produz, classifica, transmite, exibe ou registra um erro — apps mobiledesktopTV/web, CLIs, landing pages, serviços backend, e qualquer binding SDK. A classe e a severidade de um erro são as mesmas em todas as camadas: o backend que origina, o envelope que transporta, a telemetria que captura e a UI que exibe usam o mesmo valor.
R1 — Classe de erro (enum fechado)
Todo erro pertence a exatamente uma classe. O enum é fechado: um produto nunca inventa uma categoria nova — ele cria novos CODE dentro de uma categoria existente (ver user-facing-messages.kmd §4). Se nenhuma classe encaixa, é XX (e provavelmente um gap desta spec — abrir ticket).
| Classe | Nome | Domínio (o que falhou) |
|---|---|---|
DL |
Download | Obtenção de bytes de um recurso remoto para o dispositivo |
UP |
Upload | Envio de bytes do dispositivo para um recurso remoto |
AU |
Authentication | Identidade do chamador não pôde ser estabelecida/provada |
NW |
Network | Transporte/conectividade (DNS, TLS, timeout, sem rota) |
DB |
Database / storage | Camada de persistência remota (query, constraint, indisponível) |
UI |
UI render | Renderizaçãolayoutbinding na camada de apresentação |
IO |
Filesystem / local I/O | Sistema de arquivos local, dispositivo, periférico |
PM |
Permission | Identidade conhecida mas não autorizada para a ação |
VL |
Validation | Input não satisfaz uma regra (ver specs/data/validation.kmd) |
XX |
Unknown | Não classificável; fallback exclusivo |
Os 2 caracteres são o componente CATEGORY do Error ID (<PRODUCT>-<CATEGORY>-<CODE>-<SEQ>) e o valor de error_category no envelope (model.kmd) e na telemetria (reporting.kmd Group D).
R2 — Definição semântica + regra de desempate
Pares de classes confundem-se na prática. A tabela abaixo é normativa para o desempate; havendo ambiguidade, vale a coluna "Decisão".
| Confusão | Classe A | Classe B | Decisão |
|---|---|---|---|
| Não logado vs sem permissão | AU (quem é você?) |
PM (você não pode) |
401-equivalente → AU; 403-equivalente → PM. Identidade ausente/expirada = AU; identidade válida mas escopo insuficiente = PM |
| Falha de rede vs storage remoto | NW (transporte) |
DB (a query/recurso) |
Não chegou ao servidor (timeout, DNS, TLS, connection refused) = NW. Chegou e o backend de persistência falhou (5xx de query, constraint, lock) = DB |
| Download vs network | DL (semântica: obter recurso) |
NW (mecânica: transporte) |
Se o propósito da operação é baixar um recurso identificável, DL mesmo que a causa raiz seja de rede — a classe descreve a operação do usuário, a causa raiz vai em cause/http_status do envelope. NW é para falha de conectividade sem semântica de recurso (ex.: health-check, handshake) |
| Filesystem local vs storage remoto | IO (local) |
DB (remoto) |
Discoarquivodispositivo na máquina = IO. Persistência atrás de uma API/rede = DB |
| Input inválido vs erro de UI | VL (dado não passa regra) |
UI (render quebrou) |
Valor que viola uma regra de campo = VL. Falha ao desenhar/compor a tela = UI |
Princípio: a classe descreve a operação que o usuário tentava (intent), não necessariamente a camada técnica da causa raiz. A causa raiz vive em causehttp_statusupstream_dependency do envelope (model.kmd).
R3 — Severidade (escala fechada)
Todo erro carrega uma severidade. Enum fechado, ordenado:
| Severity | Significado | is_fatal |
Ação típica |
|---|---|---|---|
fatal |
Estado irrecuperável; o fluxo (ou o processo) não pode continuar com segurança | true |
Abortar boundary, crash report, exit code ≠ 0 |
error |
A operação falhou mas o app/serviço segue vivo; o usuário pode tentar de novo ou outra ação | false |
Exibir mensagem humanizada (user-facing-messages), permitir retry/abandono |
warning |
A operação prosseguiu de forma degradada; resultado parcial ou fallback usado | false |
Sinalizar de forma não-bloqueante; logar |
info |
Evento notável que não é falha (ex.: cancelado pelo usuário, no-op esperado) | false |
Geralmente não exibir como erro |
- O campo booleano
is_fataldereporting.kmdGroup D é derivado:is_fatal == (severity == "fatal"). Não há fonte independente. fatalmapeia aopanicabortde `codeerror-handling.kmd §R2`(invariante violada / estado impossível). Erro recuperável de input, IO ou rede nunca é
fatal— éerror(ouwarningse houve fallback).info/cancelamento:user-facing-messages.kmd §2já manda não exibirerro em cancelamento do usuário — esse caso é
severity: info.
R4 — Retryability
Ortogonal à severidade. Todo erro é classificável em retryability, e o valor deve alinhar com a política operacional de code/error-handling.kmd §R9.
| Retryability | Quando | Exemplos de classe/código |
|---|---|---|
retryable |
Repetir a mesma operação pode ter sucesso sem mudança de input | NW timeout, DBDLUP 5xx (idempotentes), 429 (respeitar Retry-After) |
not-retryable |
Repetir sem mudança falha de novo | VL (input não-corrigível por retry), AUPM (credencialescopo não melhoram), 4xx exceto 408/429 |
conditional |
Retry só após uma correção/ação (re-login, liberar espaço, corrigir campo) | AU expirado (após re-auth), IO sem espaço (após liberar), VL (após corrigir) |
O envelope (model.kmd) expõe retryable: bool (com conditional mapeado a false + um recovery hint). Esta tabela é a regra de classificação; o mecanismo de backoff/circuit-breaker é de error-handling.kmd §R9–R10.
R5 — Fingerprint (agrupamento)
O campo fingerprint de reporting.kmd Group D agrupa ocorrências do "mesmo" erro para deduplicação e contagem agregada. Regra de composição canônica:
fingerprint = hash(error_category + ":" + code + ":" + normalized_call_site)normalized_call_site=file:symbol(sem número de linha — linha mudaa cada edição e fragmentaria o agrupamento).
- Não incluir valores variáveis (IDs, paths, timestamps) no fingerprint
— isso explodiria a cardinalidade (anti-padrão de
policies/observability-first.kmd). - Dois call sites com a mesma
category+codetêm fingerprints distintos(é o que o
SEQdo Error ID também desambigua).
R6 — Extensão por produto
- Produtos adicionam
CODEs, nunca classes. OCODEé HTTP status(
503,404) para erros HTTP, ou um numérico curto definido pelo produto (user-facing-messages.kmd §4). - Cada produto registra seus pares `(category, code) → condição, mensagem,
call-site, severity, retryability
emproductdocstechnical/errors.md(o registry queuser-facing-messages.kmd §4e oerrors-catalog.md` gerado já consomem). - Severidade e retryability de um
(category, code)são *ropriedade doregistry do produto* classificadas segundo R3/R4 desta spec.
R7 — Audit determinístico
errors-taxonomy-audit.sh (advisory), rodável por /k-housekeep:
- Todo
error_categoryemitido em código/registry pertence ao enum de R1(qualquer outro valor → error).
- Todo
severityemitido pertence ao enum de R3 (→ error). is_fatalsemseverity == "fatal"correspondente → warning (campoderivado fora de sincronia).
- Registry de produto (
docs/technical/errors.md) com entrada semseverity/retryabilityclassificados → warning. fingerprintcontendo dígitos de linha ou IDs variáveis → warning(cardinalidade/fragmentação).
Cross-link
specs/errors/model.kmd— envelope máquina-legível que carregaerror_categoryseverityretryabledefinidos aqui.specs/errors/user-facing-messages.kmd— Error ID (§4referencia oenum desta spec) + texto humano.
specs/errors/reporting.kmd— Group D capturaerror_category,severity,is_fatal,fingerprint(definidos aqui).specs/code/error-handling.kmd—§R2(fatal↔panic),§R9(retry),§R10(circuit breaker).specs/data/validation.kmd— origem dos erros de classeVL.policies/observability-first.kmd— budget de cardinalidade (fingerprint, labels).