Skip to content

Commit 3358dd0

Browse files
thodson-usgsclaude
andcommitted
Fix IndexError in _read_rdb when NWIS returns no data rows
When an NWIS service responds with only comment lines (e.g. "No sites found matching all criteria"), _read_rdb tried to index past the end of the lines list and raised an unhelpful IndexError. Now it detects the empty-data case, extracts the Response-Message from the comment block, and raises a ValueError with that message instead. Fixes #171. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 8687bb5 commit 3358dd0

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

dataretrieval/nwis.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,16 +1039,26 @@ def _read_rdb(rdb):
10391039
)
10401040

10411041
count = 0
1042+
lines = rdb.splitlines()
10421043

1043-
for line in rdb.splitlines():
1044+
for line in lines:
10441045
# ignore comment lines
10451046
if line.startswith("#"):
10461047
count = count + 1
10471048

10481049
else:
10491050
break
10501051

1051-
fields = rdb.splitlines()[count].split("\t")
1052+
if count >= len(lines):
1053+
# All lines are comments — no data rows. Extract the NWIS message.
1054+
msg = "No data returned from the NWIS service."
1055+
for line in lines:
1056+
if "Response-Message:" in line:
1057+
msg = line.split("Response-Message:")[-1].strip()
1058+
break
1059+
raise ValueError(msg)
1060+
1061+
fields = lines[count].split("\t")
10521062
fields = [field.replace(",", "").strip() for field in fields if field.strip()]
10531063
dtypes = {
10541064
"site_no": str,

tests/nwis_test.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from dataretrieval.nwis import (
1111
NWIS_Metadata,
12+
_read_rdb,
1213
get_discharge_measurements,
1314
get_gwlevels,
1415
get_info,
@@ -321,3 +322,44 @@ def test_variable_info_deprecated(self):
321322
):
322323
result = md.variable_info
323324
assert result is None
325+
326+
327+
class TestReadRdb:
328+
"""Tests for the _read_rdb helper.
329+
330+
Notes
331+
-----
332+
Related to GitHub Issue #171.
333+
"""
334+
335+
# Minimal valid RDB response with one data row
336+
_VALID_RDB = (
337+
"# comment\n"
338+
"site_no\tvalue\n"
339+
"5s\t10n\n"
340+
"01491000\t42\n"
341+
)
342+
343+
# NWIS response when no sites match the query criteria
344+
_NO_SITES_RDB = (
345+
"# //Output-Format: RDB\n"
346+
"# //Response-Status: OK\n"
347+
"# //Response-Message: No sites found matching all criteria\n"
348+
)
349+
350+
def test_valid_rdb_returns_dataframe(self):
351+
"""_read_rdb returns a DataFrame for a well-formed RDB response."""
352+
df = _read_rdb(self._VALID_RDB)
353+
assert isinstance(df, pd.DataFrame)
354+
assert "site_no" in df.columns
355+
356+
def test_no_sites_raises_value_error(self):
357+
"""_read_rdb raises ValueError when NWIS returns no data rows (issue #171)."""
358+
with pytest.raises(ValueError, match="No sites found"):
359+
_read_rdb(self._NO_SITES_RDB)
360+
361+
def test_empty_comments_raises_value_error(self):
362+
"""_read_rdb raises a generic ValueError when response has only comments."""
363+
rdb = "# just a comment\n# another comment\n"
364+
with pytest.raises(ValueError):
365+
_read_rdb(rdb)

0 commit comments

Comments
 (0)