Skip to content

Commit

Permalink
Properly deal with empty responses
Browse files Browse the repository at this point in the history
  • Loading branch information
ehrenfeu committed Jun 21, 2023
1 parent a282be4 commit 7627d08
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ NOTE: potentially breaking changes are flagged with a 🧨 symbol.
be None (in which case a fixed string is returned).
- `pyppms.booking.PpmsBooking.desc` has been added as a property to retrieve a
shorter description of the object than calling `str()` on it.
- `pyppms.exceptions.NoDataError` has been added to indicate a PUMAPI response
did *not* contain any useful data.
- `pyppms.common.parse_multiline_response()` will now raise the newly added
`NoDataError` in case the requested *runningsheet* for a day doesn't contain
any bookings to allow for properly dealing with "empty" days.

### Changed

Expand Down
17 changes: 13 additions & 4 deletions src/pyppms/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from loguru import logger as log

from .exceptions import NoDataError


def process_response_values(values):
"""Process (in-place) a list of strings, remove quotes, detect boolean etc.
Expand Down Expand Up @@ -120,11 +122,15 @@ def parse_multiline_response(text, graceful=True):
-------
list(dict)
A list with dicts where the latter ones have the same form as produced
by the dict_from_single_response() function. Note that when graceful
by the dict_from_single_response() function. May be empty in case the
PUMAPI response didn't contain any useful data. Note that when graceful
mode is requested, consistency among the dicts is not guaranteed.
Raises
------
NoDataError
Raised when the response text was too short (less than two lines) and
the `graceful` parameter has been set to false.
ValueError
Raised when the response text is inconsistent and the `graceful`
parameter has been set to false, or if parsing fails for any other
Expand All @@ -134,10 +140,10 @@ def parse_multiline_response(text, graceful=True):
try:
lines = text.splitlines()
if len(lines) < 2:
log.warning("Response expected to have two or more lines: {}", text)
log.info("Response has less than TWO lines: >>>{}<<<", text)
if not graceful:
raise ValueError("Invalid response format!")
return parsed
raise NoDataError("Invalid response format!")
return []

header = lines[0].split(",")
for i, entry in enumerate(header):
Expand Down Expand Up @@ -174,6 +180,9 @@ def parse_multiline_response(text, graceful=True):
)
log.warning(msg)

except NoDataError as err:
raise err

except Exception as err:
msg = f"Unable to parse data returned by PUMAPI: {text} - ERROR: {err}"
log.error(msg)
Expand Down
5 changes: 5 additions & 0 deletions src/pyppms/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""PyPPMS exception classes."""


class NoDataError(ValueError):
"""Exception indicating no data was received from PUMAPI."""
11 changes: 7 additions & 4 deletions src/pyppms/ppms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .user import PpmsUser
from .system import PpmsSystem
from .booking import PpmsBooking
from .exceptions import NoDataError


class PpmsConnection:
Expand Down Expand Up @@ -596,12 +597,14 @@ def get_running_sheet(self, core_facility_ref, date, ignore_uncached_users=False
response = self.request("getrunningsheet", parameters)
try:
entries = parse_multiline_response(response.text, graceful=False)
except NoDataError:
# in case no bookings exist the response will be empty!
log.debug("Runningsheet for the given day was empty!")
return []
except Exception as err: # pylint: disable-msg=broad-except
log.error("Parsing runningsheet details failed: {}", err)
# NOTE: in case no future bookings exist the response will be empty!
log.error("Possibly the runningsheet is empty as no bookings exist?")
log.debug("Runningsheet PUMPAI response was: {}", response.text)
return bookings
log.debug("Runningsheet PUMPAI response was: >>>{}<<<", response.text)
return []

for entry in entries:
full = entry["User"]
Expand Down

0 comments on commit 7627d08

Please sign in to comment.