Skip to content

Commit 32c7bf6

Browse files
committed
Add: exceptions constant for api access retries
We have seen problems with the application when the nvd API responds properly http wise, but delivers json that cannot be decoded properly. To keep retrying these API calls with the already existing retry functionality until they succeed, which currently happens after ~ 1-5 tries, we need to use a tuple with the already used http error and also JSONDecodeError. As this happens multiple times, we use a constant that can be used in multiple places. The constant is in a new constants file to avoid circular dependencies from code that is called from the cli module back to the cli module itself. TODO: 1) We should refactor these accesses afterwards when the high prio for production fix is done, in order to have this functionality reusable in one place, because having the basically same stamina call in so many places calls for improvement. 2) also mode the existing constans from cli.py into wht constants file, also to avoid circular dependencies.
1 parent 9af37ac commit 32c7bf6

4 files changed

Lines changed: 18 additions & 7 deletions

File tree

greenbone/scap/constants.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-FileCopyrightText: 2025 Greenbone AG
2+
#
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
from json import JSONDecodeError
5+
6+
from httpx import HTTPError
7+
8+
# Exceptions on API access to catch in order to retry these calls
9+
STAMINA_API_RETRY_EXCEPTIONS = (JSONDecodeError, HTTPError)

greenbone/scap/cpe/cli/download.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
CLIError,
3030
CLIRunner,
3131
)
32+
from greenbone.scap.constants import STAMINA_API_RETRY_EXCEPTIONS
3233
from greenbone.scap.cpe.manager import CPEManager
3334
from greenbone.scap.db import PostgresDatabase
3435
from greenbone.scap.timer import Timer
@@ -206,7 +207,7 @@ async def _producer(
206207
with Timer() as download_timer:
207208
count = 0
208209
async for attempt in stamina.retry_context(
209-
on=httpx.HTTPError,
210+
on=STAMINA_API_RETRY_EXCEPTIONS,
210211
attempts=retry_attempts,
211212
timeout=None,
212213
):
@@ -250,7 +251,7 @@ async def download(
250251
last_modified_end_date: datetime | None,
251252
) -> None:
252253
async for attempt in stamina.retry_context(
253-
on=httpx.HTTPError,
254+
on=STAMINA_API_RETRY_EXCEPTIONS,
254255
attempts=retry_attempts,
255256
timeout=None,
256257
):

greenbone/scap/cve/cli/download.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from pathlib import Path
1010
from typing import Sequence
1111

12-
import httpx
1312
import shtab
1413
import stamina
1514
from pontos.nvd import now
@@ -29,6 +28,7 @@
2928
CLIError,
3029
CLIRunner,
3130
)
31+
from greenbone.scap.constants import STAMINA_API_RETRY_EXCEPTIONS
3232
from greenbone.scap.cve.manager import CVEManager
3333
from greenbone.scap.db import PostgresDatabase
3434
from greenbone.scap.timer import Timer
@@ -212,7 +212,7 @@ async def _producer(
212212
with Timer() as download_timer:
213213
count = 0
214214
async for attempt in stamina.retry_context(
215-
on=httpx.HTTPError,
215+
on=STAMINA_API_RETRY_EXCEPTIONS,
216216
attempts=retry_attempts,
217217
timeout=None,
218218
):
@@ -255,7 +255,7 @@ async def download(
255255
last_modified_end_date: datetime | None,
256256
) -> None:
257257
async for attempt in stamina.retry_context(
258-
on=httpx.HTTPError,
258+
on=STAMINA_API_RETRY_EXCEPTIONS,
259259
attempts=retry_attempts,
260260
timeout=None,
261261
):

greenbone/scap/generic_cli/producer/nvd_api.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
DEFAULT_RETRIES,
1818
DEFAULT_VERBOSITY,
1919
)
20+
from ...constants import STAMINA_API_RETRY_EXCEPTIONS
2021

2122
from ...timer import Timer
2223
from .base import BaseScapProducer
@@ -222,7 +223,7 @@ async def fetch_initial_data(
222223
The number of expected items.
223224
"""
224225
async for attempt in stamina.retry_context(
225-
on=httpx.HTTPError,
226+
on=STAMINA_API_RETRY_EXCEPTIONS,
226227
attempts=self._retry_attempts,
227228
timeout=None,
228229
):
@@ -275,7 +276,7 @@ async def run_loop(
275276
with Timer() as download_timer:
276277
count = 0
277278
async for attempt in stamina.retry_context(
278-
on=httpx.HTTPError,
279+
on=STAMINA_API_RETRY_EXCEPTIONS,
279280
attempts=self._additional_retry_attempts,
280281
timeout=None,
281282
):

0 commit comments

Comments
 (0)