fix(cnpj): limita consultas e sinaliza indisponibilidade do provedor … · BrasilAPI/BrasilAPI@0c229b4 · GitHub
Skip to content

Commit 0c229b4

Browse files
authored
fix(cnpj): limita consultas e sinaliza indisponibilidade do provedor (#923)
1 parent 4b552e7 commit 0c229b4

5 files changed

Lines changed: 287 additions & 2 deletions

File tree

‎errors/ServiceUnavailableError.js‎

Lines changed: 12 additions & 0 deletions

‎pages/api/cnpj/v1/[cnpj].js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
import app from '@/app';
22
import BadRequestError from '@/errors/BadRequestError';
33
import NotFoundError from '@/errors/NotFoundError';
4+
import ServiceUnavailableError from '@/errors/ServiceUnavailableError';
45
import { getCnpjData } from '@/services/cnpj';
56

67
async function getCnpjInfo(request, response) {
78
try {
89
const result = await getCnpjData(request.query.cnpj);
910
return response.status(result.status).json(result.data);
1011
} catch (error) {
12+
if (error instanceof ServiceUnavailableError) {
13+
response.setHeader('Cache-Control', 'no-store');
14+
throw error;
15+
}
1116
if (error.response?.status === 400) {
1217
throw new BadRequestError({ message: error.response.data.message });
1318
}

‎pages/docs/doc/cnpj.json‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@
5252
}
5353
}
5454
},
55+
"503": {
56+
"description": "Serviço de consulta temporariamente indisponível: falha ou tempo limite de 5 segundos na API Minha Receita. A resposta não deve ser armazenada em cache.",
57+
"content": {
58+
"application/json": {
59+
"schema": {
60+
"$ref": "#/components/schemas/ErrorMessage"
61+
},
62+
"example": {
63+
"name": "ServiceUnavailableError",
64+
"message": "Serviço de consulta de CNPJ temporariamente indisponível.",
65+
"type": "service_unavailable"
66+
}
67+
}
68+
}
69+
},
5570
"404": {
5671
"description": "CNPJ não encontrado na API Minha Receita.",
5772
"content": {

‎services/cnpj.js‎

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
11
import axios from 'axios';
2+
import ServiceUnavailableError from '@/errors/ServiceUnavailableError';
23

3-
export const getCnpjData = (cnpj) =>
4-
axios.get(`https://minhareceita.org/${cnpj}`);
4+
const PROVIDER_TIMEOUT_MS = 5000;
5+
6+
export const getCnpjData = async (cnpj) => {
7+
const controller = new AbortController();
8+
// Bound the whole request, including connection establishment.
9+
const deadline = setTimeout(() => controller.abort(), PROVIDER_TIMEOUT_MS);
10+
11+
try {
12+
return await axios.get(`https://minhareceita.org/${cnpj}`, {
13+
timeout: PROVIDER_TIMEOUT_MS,
14+
signal: controller.signal,
15+
});
16+
} catch (error) {
17+
const status = error.response?.status;
18+
if (
19+
axios.isAxiosError(error) &&
20+
((status >= 500 && status <= 599) ||
21+
(!error.response && (error.request || controller.signal.aborted)))
22+
) {
23+
throw new ServiceUnavailableError({
24+
message: 'Serviço de consulta de CNPJ temporariamente indisponível.',
25+
});
26+
}
27+
throw error;
28+
} finally {
29+
clearTimeout(deadline);
30+
}
31+
};

‎tests/cnpj-contract.test.js‎

Lines changed: 226 additions & 0 deletions

0 commit comments

Comments
 (0)