Visão geral e objetivo
Quando usuários encontram erros, eles merecem feedback claro explicando o que aconteceu e como corrigir. Mensagens brutas do backend precisam ser normalizadas para:
- Remover ruído: retirar prefixos "Error:" redundantes e limpar espaços
- Evitar vazamentos: garantir que detalhes sensíveis de implementação nunca cheguem ao usuário
- Fornecer fallbacks: mostrar mensagens seguras quando erros estão vazios ou malformados
- Garantir consistência: aplicar a mesma lógica em todos os 11+ módulos frontend
- Melhorar debugging: registrar detalhes completos no Phantom Wing enquanto usuários veem resumos seguros
O problema: erros genéricos versus mensagens úteis
Antes da padronização, os módulos da PayCal usavam tratamento de erro ad hoc:
// ❌ BAD: Exposes raw error, duplicates logic
PC.showToast(error?.message || 'Import failed.');
PW.error(`Import failed: ${error.message}`);
Problemas dessa abordagem:
- Usuários veem mensagens brutas confusas como "ECONNREFUSED: Connection refused"
- Cada módulo implementa sua própria lógica de fallback independentemente
- Não há limpeza consistente de espaços nem remoção de prefixos
- Mensagens vazias podem aparecer como "undefined" na UI
A solução: resolvedor de erro padronizado
Todos os módulos frontend da PayCal agora usam uma função resolvedora unificada que normaliza mensagens de erro:
// ✅ GOOD: Normalized, consistent, safe
const resolveThrownMessage = (error, fallbackMessage) => {
const raw = typeof error?.message === 'string'
? error.message
: String(error || '');
const normalized = raw.replace(/^Error:\s*/i, '').trim();
return normalized !== '' ? normalized : fallbackMessage;
};
Uso:
// In catch blocks across modules
try {
await updateProfile(data);
} catch (error) {
const message = resolveThrownMessage(error, 'Unable to update profile.');
PC.showToast(message, 'error'); // User sees meaningful feedback
PW.error(message); // Logged for debugging
}
Escopo de implementação
Em abril de 2026, esse padrão foi aplicado a 11 módulos frontend com aproximadamente 40+ blocos catch normalizados:
Autenticação e configurações (7 módulos)
html/js/auth-recovery/index.php(4 catches)html/js/signin/index.php(2 catches)html/js/signin/verification-reminder.js(2 catches)html/js/signin/verification-status-banner.js(1 catch)html/js/settings/index.php(8+ catches)
Módulos core e de dados (4 módulos)
html/js/core/network.js(3 catches)html/js/core/index.php(5 catches)html/js/core/billing.js(5 catches)html/js/earnings/index.php(4 catches)
Módulos de alto valor (10+ pontos catch):
html/js/organizations/index.php- Org management, access requests, audit trails (19+ catches)html/js/sites/index.php- Site CRUD, earnings, orphan work recovery (10+ catches)html/js/calendar/calendar.js- Day-entry operations, copy/paste/delete (2 catches)
Categorias de erro e padrões de tratamento
O resolvedor é aplicado de forma consistente em várias categorias de erro:
1. Falhas de requisições de rede
// Network module: HTTP errors, timeouts, connection issues
async function deleteResource(ep, id) {
try {
// ...fetch logic...
} catch (error) {
const resolved = resolveThrownMessage(error, 'Network error');
const msg = `[deleteResource] ${resolved}`;
PW.error(msg);
throw new Error(msg);
}
}
2. Tratamento de respostas API
// Billing/Settings: Server returned error message in payload
try {
const response = await fetch('/api/v1/billing/subscription');
const payload = await response.json();
if (!response.ok) {
throw new Error(payload?.message || 'Unable to load billing status.');
}
} catch (error) {
const resolved = resolveThrownMessage(error, 'Unable to load billing status.');
setScreenReaderStatus(resolved);
}
3. Falhas de operações de UI
// Calendar/Organizations: User-initiated actions (paste, delete, update)
button.addEventListener('click', async () => {
try {
await performAction();
PC.showToast('Success!', 'save');
} catch (error) {
const message = resolveThrownMessage(error, 'Action failed. Try again.');
PC.showToast(message, 'error');
}
});
4. Inicialização assíncrona
// Core modules: Startup or dependent initialization failures
try {
NavigationToggle.init();
} catch (err) {
const resolved = resolveThrownMessage(err, 'Navigation init failed');
PW.warn(resolved); // Logged but doesn't block page
}
Considerações de segurança
A normalização de mensagens protege a privacidade do usuário e a integridade do sistema:
- Sem detalhes de banco: erros backend como "UNIQUE constraint failed on email" são interceptados na fronteira da API
- Sem caminhos de arquivo: erros de sistema que expõem caminhos ou processos são removidos
- Sem vazamento de autenticação: falhas de login nunca revelam se uma conta existe
- Sem detalhes CORS/rede: erros de transporte viram mensagens genéricas de conexão
- Fallbacks seguros: todos os catchers têm mensagens explícitas; nunca exibem "undefined" ou "null"
Benefícios para a experiência do usuário
Essa padronização dá aos usuários feedback mais claro, seguro e consistente, enquanto facilita suporte e debugging.
- Mensagens são compreensíveis sem expor detalhes de implementação
- O texto fallback permanece seguro quando o erro do backend falta ou é malformado
- Logs continuam úteis para debugging sem vazar valores sensíveis para a UI
Fluxo de debugging e suporte
A equipe de suporte pode confiar em um caminho de resolvedor consistente e consultar logs do Phantom Wing quando precisar do detalhe técnico completo.
- Usuário vê mensagem normalizada
- Phantom Wing registra o contexto completo do erro de forma privada
- Suporte correlaciona a classe do problema sem expor a resposta bruta do backend
Testes e garantia de qualidade
A lógica de normalização é coberta por testes focados de módulo e checks de integração nos principais fluxos frontend.
Manutenção e extensões futuras
Conforme a PayCal adiciona módulos, o mesmo padrão de resolvedor deve ser reutilizado em vez de duplicar formatação personalizada.
- Novos módulos devem chamar diretamente o resolvedor compartilhado
- Mensagens fallback específicas devem permanecer curtas e voltadas ao usuário
- Mudanças no resolvedor devem ter regressão em fluxos representativos
Isso mantém o comportamento previsível à medida que a base cresce e evita uma nova geração de tratamento de erro por módulo.
Resumo: o padrão PayCal de tratamento de erros
A PayCal padronizou o tratamento de erros frontend para que usuários recebam mensagens seguras e consistentes enquanto desenvolvedores preservam informações necessárias para debugging.
- Normalizar mensagens antes da exibição
- Ocultar detalhes de implementação dos usuários
- Usar fallback explícito para erros vazios ou malformados
- Registrar detalhes técnicos privadamente para suporte e debugging