Ir para o conteúdo

Tratamento de erros ​

← Índice da documentação da API

Fontes: controller/exception/GlobalExceptionHandler.java, mes/MesErrors.java, mes/MesEdgeSecurity.java, config/LoginRateLimitingFilter.java, config/PreflightAwareAuthenticationEntryPoint.java, util/MensagemErro.java, e, no frontend, src/axios.ts e src/utils/userFacingError.ts.

1. Formato padrão de erro (ErrorResponseDTO) ​

A maior parte dos erros sai pelo GlobalExceptionHandler neste formato:

json
{
  "timestamp": "2026-10-15T09:41:07.123456",
  "status": 400,
  "error": "Bad Request",
  "message": "Descrição legível do problema.",
  "path": "/api/produtos"
}
CampoTipoObservação
timestampLocalDateTime ISO-8601hora do servidor, sem fuso
statusinteiromesmo valor do status HTTP
errortextodescrição padrão do status HTTP em inglês (Bad Request, Conflict...)
messagetextoem português, é o texto mostrado ao usuário pelo frontend; se vier vazio vira Erro interno inesperado.
pathtextoURI da requisição

2. Mapeamento exceção → status (cadeia global) ​

Situação / exceçãoStatusmessage
Bean Validation falhou (@Valid)400mensagens dos campos separadas por ; (ou Dados inválidos.)
IllegalArgumentException400a mensagem da exceção (regra de negócio violada)
DataIntegrityViolationException400Já existe um produto com este código Wester... (violação de codigo_sistema_wester); Registro duplicado detectado. Verifique os campos únicos.; Não foi possível concluir a operação por vínculo com outros registros.; ou Violação de integridade de dados. Verifique os campos enviados.
InvalidCredentialsException401Usuário ou senha inválidos. / Informe login e senha para continuar.
AuthenticationCredentialsNotFoundException401mensagem da exceção
InactiveUserException403Usuário inativo. Procure um administrador.
AuthorizationDeniedException (falha de @PreAuthorize)403Você não tem permissão para executar esta ação.
RuntimeException cuja mensagem contém "não encontrad(o/a)"404a mensagem (comparação sem acento e sem gênero, via MensagemErro)
HttpRequestMethodNotSupportedException405mensagem do Spring
IllegalStateException409a mensagem (conflito de estado)
Conflito de versão otimista (ObjectOptimisticLockingFailureException, OptimisticLockException)409OPTIMISTIC_LOCK: O registro foi alterado por outro usuário. Atualize os dados e tente novamente.
ResponseStatusExceptiono status da exceçãoreason da exceção
Qualquer outra RuntimeException / Exception500mensagem da exceção; erro registrado em log
Cliente desconectou no meio da resposta (AsyncRequestNotUsableException)—apenas log em nível debug; não gera corpo

Pontos a saber:

  • O prefixo OPTIMISTIC_LOCK: na mensagem é um contrato com o frontend, que abre o ConflictDialog ("alterado por outro usuário"). Entidades com controle de versão (@Version) no código: Fileira, Grade, Nivel e ItemEstoque (campo version).
  • 404 depende do texto da mensagem. Uma exceção genérica só vira 404 se a mensagem contiver "não encontrad…"; se o texto mudar, o status passa a 500. Está documentado no próprio utilitário MensagemErro.
  • O texto de IllegalArgumentException e IllegalStateException vai direto ao cliente. Por isso as mensagens dos serviços são escritas em português para o usuário final.

3. Formatos de erro diferentes do padrão ​

Nem todo erro usa o ErrorResponseDTO. Integradores devem tratar estes formatos:

OrigemStatusCorpo
UsuarioController (criar, atualizar, alterar senha, status, excluir)400, 403, 404, 500texto puro (String) no corpo, por exemplo Senha é obrigatória. e Você não tem permissão para alterar a senha de outra conta.
MES — MesErrors (apenas rotas de MesController)400, status de ResponseStatusException, 403{"message": "..."} (Dados invalidos, Operacao recusada, Sem permissao quando não há texto)
Edge — MesEdgeSecurity401 ou 503{"message":"Integracao edge indisponivel ou credencial invalida"}
Limite de taxa — LoginRateLimitingFilter429{"status":429,"error":"Too Many Requests","message":"Muitas tentativas. Aguarde um momento antes de tentar novamente."}
Falta de autenticação na cadeia principal (PreflightAwareAuthenticationEntryPoint)401sem corpo (apenas o status); um pré-voo CORS recebe 200

PreflightAwareAuthenticationEntryPoint define apenas o status: 401 sem corpo quando falta autenticação em uma rota protegida (e 200 para pré-voo CORS). Um cliente não deve esperar ErrorResponseDTO nesse caso.

Os controllers do MES que respondem ResponseStatusException seguem MesErrors, não o handler global, porque o @RestControllerAdvice do MES tem @Order(0) e escopo basePackageClasses=MesController.class.

4. Códigos HTTP que a API pode devolver ​

StatusQuando
200consulta ou alteração com corpo
201criação (POST /api/usuarios e outras criações que declaram 201)
204alteração sem corpo (por exemplo, troca de senha)
400validação, regra de negócio, integridade de dados, JSON inválido
401token ausente/inválido/expirado, usuário ou senha inválidos, chave do Edge incorreta
403usuário inativo, falta de permissão (SCREEN_*/FULL_ACCESS/MES)
404recurso não encontrado
405método HTTP não suportado na rota
409conflito de estado ou de versão (otimista); MES também usa para sequência de eventos do coletor
429excesso de tentativas de login/cadastro por IP
500erro não tratado
503integração Edge indisponível (chave não configurada)

Cada ficha de endpoint (modulos/*.md) lista os códigos declarados e as mensagens de validação identificadas no serviço. Ela não garante que todas as mensagens possíveis estejam listadas: as mensagens dinâmicas e as que vêm de métodos auxiliares aparecem em documento interno de regras de negócio.

5. Como o frontend trata os erros (para o manual e para integradores) ​

  • 401 com token anexado: o axios dispara o handler de não autorizado, que faz logout e volta para a tela de Login (o token vale 8 horas).
  • Mensagem exibida: getUserFacingErrorMessage usa o message da API, descartando textos técnicos (network error, internal server error, not found, timeout, 404, 500, HTML, stack trace...) e caindo na mensagem padrão da tela. Para 401/403 sem texto aproveitável, mostra Você não tem permissão para concluir esta operação.
  • Conflito 409: mostra a mensagem da API ou Os dados foram alterados por outro usuário. Atualize a tela e tente novamente.
  • Login: 401 → E-mail ou senha inválidos.; 403 → Seu usuário não pode acessar o sistema.; sem resposta do servidor → Não foi possível conectar ao servidor. Tente novamente.

6. Recomendações para quem integra ​

  1. Trate o corpo de erro como texto ou JSON dependendo da rota (seção 3); verifique o Content-Type.
  2. Use o status HTTP como contrato; o message é para pessoas e pode mudar.
  3. Em 409 com prefixo OPTIMISTIC_LOCK:, releia o recurso (incluindo version) antes de tentar de novo.
  4. Em 429, espere um minuto antes de repetir.
  5. Para o Edge, 503 significa que a chave não está configurada no servidor (não é erro do coletor), e 401 que a chave enviada não confere.

Manual do usuário — Sistema Wester. Conteúdo descreve as telas conforme a versão indicada na página inicial.