
Introdução
Nesse artigo você vai aprender a como resolver o problema emitindo o status 22003 no banco de dados.
Contexto
Em um dia desses eu estava fazendo deploy de uma aplicação com Adonis e Postgres no Heroku, até que recebo as seguintes mensagens de log:
Logs do erro
heroku[router]: at=banlanco-patrimonial method=PUT path="/banlanco-patrimonial/7" host=<website>.herokuapp.com request_id=<id> fwd=<fwd> dyno=web.1 connect=0ms service=7ms status=500 bytes=1101 protocol=httpsapp[web.1]: [1650719030687] ERROR (banco-de-dados/22 on <hash>): update "balanco_patrimonial_dres" set "clientes_a_receber" = $1, "updated_at" = $2 where "id" = $3 - numeric field overflowapp[web.1]: x-request-id: <id>app[web.1]: request_id: <id>app[web.1]: err: {app[web.1]: "type": "DatabaseError",app[web.1]: "message": "update \"balanco_patrimonial_dres\" set \"clientes_a_receber\" = $1, \"updated_at\" = $2 where \"id\" = $3 - numeric field overflow",app[web.1]: "stack":app[web.1]: error: update "balanco_patrimonial_dres" set "clientes_a_receber" = $1, "updated_at" = $2 where "id" = $3 - numeric field overflowapp[web.1]: at Parser.parseErrorMessage (/app/node_modules/pg-protocol/src/parser.ts:369:69)app[web.1]: "length": 164,app[web.1]: "name": "error",app[web.1]: "severity": "ERROR",app[web.1]: "code": "22003",app[web.1]: "detail": "A field with precision 8, scale 2 must round to an absolute value less than 10^6.",app[web.1]: "file": "numeric.c",app[web.1]: "line": "6589",app[web.1]: "routine": "apply_typmod",app[web.1]: "status": 500app[web.1]: }
O que está acontecendo?
Está emitido ostatus 22003 no banco de dados, isso significa que o valor numérico está fora do intervalo. Então pode ser que o valor está muito alto, ou muito baixo do esperado.
De acordo comData Vault Message Reference:
22003
Data exception - numeric value out of range
This message appears when an SQL operation results in a numeric overflow or underflow. That is, an evaluated numeric expression is either too large or too small to be contained in a suitable datatype without loss of precision or scale.
Possível solução:
Uma possível solução para este problema seria a troca o tipo de dados numérico que serão recebidos na requisição da API
Exemplos de valores altos que estão atrapalhando nas requisições:
"estoques": 1502412,"imobilizados": 1386896,"fornecedores": 1417072,"clientes_a_receber": 2091280,"capital_e_reservas": 1314166,"receitas_operacionais_brutas": 12226104,"impostos_incidentes_sobre_vendas": -2420768.59,"custo_dos_produtos_vendidos": -7101833.06,
OBS.: Regex utilizado para verificar que valores estão altos:\-?[0-9]{7,}
ou\"[a-z]{1,}\"\: \-?[0-9]{7,}
Decimal
Começando pelo tipo de dado que estou usando, o tipodecimal é a melhor escolha quando se envolve dinheiro e finança por trazer uma grande precisão para evitar erros de arredondamento. Porém, no meu caso está emitindo o erro de valor fora do intervalo numérico pois, o número é muito grande.
Float e Double
Então a possível solução é trocar o tipo parafloat oudouble. Caso tenha dúvida da escolha entre esses dois tipos a diferença seria a precisão, a variação e a quantidade de casas decimais que consegue suportar.
Esses tipos são chamados ponto flutuante binários:
Tipo | Bits | Descrição |
---|---|---|
Float | 32 bits | Tem 24 dígitos de precisão e por isso é chamado de simples precisão |
Double | 64 bits | Tem 53 dígitos de precisão e é chamado de dupla precisão |
Conclusão
Então minha escolha/solução foi a troca do tipo de dadosDECIMAL pelo o tipoFLOAT, apesar de oDOUBLE ter uma precisão maior e suportar uma quantidade maior de casas decimais no meu caso não seria necessário.
Me acompanhe no meu...
Website:carlosalves.vercel.app
Gitub:@EuCarlos
Dribbble:@EuCarlos
LinkedIn:linkedin.com/in/josecarlos98
Referencias:
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse