Tema
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.tsesrc/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"
}| Campo | Tipo | Observação |
|---|---|---|
timestamp | LocalDateTime ISO-8601 | hora do servidor, sem fuso |
status | inteiro | mesmo valor do status HTTP |
error | texto | descrição padrão do status HTTP em inglês (Bad Request, Conflict...) |
message | texto | em português, é o texto mostrado ao usuário pelo frontend; se vier vazio vira Erro interno inesperado. |
path | texto | URI da requisição |
2. Mapeamento exceção → status (cadeia global)
| Situação / exceção | Status | message |
|---|---|---|
Bean Validation falhou (@Valid) | 400 | mensagens dos campos separadas por ; (ou Dados inválidos.) |
IllegalArgumentException | 400 | a mensagem da exceção (regra de negócio violada) |
DataIntegrityViolationException | 400 | Já 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. |
InvalidCredentialsException | 401 | Usuário ou senha inválidos. / Informe login e senha para continuar. |
AuthenticationCredentialsNotFoundException | 401 | mensagem da exceção |
InactiveUserException | 403 | Usuário inativo. Procure um administrador. |
AuthorizationDeniedException (falha de @PreAuthorize) | 403 | Você não tem permissão para executar esta ação. |
RuntimeException cuja mensagem contém "não encontrad(o/a)" | 404 | a mensagem (comparação sem acento e sem gênero, via MensagemErro) |
HttpRequestMethodNotSupportedException | 405 | mensagem do Spring |
IllegalStateException | 409 | a mensagem (conflito de estado) |
Conflito de versão otimista (ObjectOptimisticLockingFailureException, OptimisticLockException) | 409 | OPTIMISTIC_LOCK: O registro foi alterado por outro usuário. Atualize os dados e tente novamente. |
ResponseStatusException | o status da exceção | reason da exceção |
Qualquer outra RuntimeException / Exception | 500 | mensagem 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 oConflictDialog("alterado por outro usuário"). Entidades com controle de versão (@Version) no código:Fileira,Grade,NiveleItemEstoque(campoversion). - 404 depende do texto da mensagem. Uma exceção genérica só vira
404se a mensagem contiver "não encontrad…"; se o texto mudar, o status passa a500. Está documentado no próprio utilitárioMensagemErro. - O texto de
IllegalArgumentExceptioneIllegalStateExceptionvai 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:
| Origem | Status | Corpo |
|---|---|---|
UsuarioController (criar, atualizar, alterar senha, status, excluir) | 400, 403, 404, 500 | texto 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 — MesEdgeSecurity | 401 ou 503 | {"message":"Integracao edge indisponivel ou credencial invalida"} |
Limite de taxa — LoginRateLimitingFilter | 429 | {"status":429,"error":"Too Many Requests","message":"Muitas tentativas. Aguarde um momento antes de tentar novamente."} |
Falta de autenticação na cadeia principal (PreflightAwareAuthenticationEntryPoint) | 401 | sem 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
| Status | Quando |
|---|---|
200 | consulta ou alteração com corpo |
201 | criação (POST /api/usuarios e outras criações que declaram 201) |
204 | alteração sem corpo (por exemplo, troca de senha) |
400 | validação, regra de negócio, integridade de dados, JSON inválido |
401 | token ausente/inválido/expirado, usuário ou senha inválidos, chave do Edge incorreta |
403 | usuário inativo, falta de permissão (SCREEN_*/FULL_ACCESS/MES) |
404 | recurso não encontrado |
405 | método HTTP não suportado na rota |
409 | conflito de estado ou de versão (otimista); MES também usa para sequência de eventos do coletor |
429 | excesso de tentativas de login/cadastro por IP |
500 | erro não tratado |
503 | integraçã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)
401com token anexado: oaxiosdispara o handler de não autorizado, que faz logout e volta para a tela de Login (o token vale 8 horas).- Mensagem exibida:
getUserFacingErrorMessageusa omessageda 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. Para401/403sem texto aproveitável, mostraVocê não tem permissão para concluir esta operação. - Conflito
409: mostra a mensagem da API ouOs 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
- Trate o corpo de erro como texto ou JSON dependendo da rota (seção 3); verifique o
Content-Type. - Use o
statusHTTP como contrato; omessageé para pessoas e pode mudar. - Em
409com prefixoOPTIMISTIC_LOCK:, releia o recurso (incluindoversion) antes de tentar de novo. - Em
429, espere um minuto antes de repetir. - Para o Edge,
503significa que a chave não está configurada no servidor (não é erro do coletor), e401que a chave enviada não confere.