Skip to content

Commit 586f49f

Browse files
committed
chore: improve user-facing error messages
Make internal validation errors more actionable by avoiding private variable names, clarifying required inputs (e.g. AIM palette order), and suggesting filing a GitHub issue for invariants that should never fail. Made-with: Cursor
1 parent df84a65 commit 586f49f

5 files changed

Lines changed: 43 additions & 23 deletions

File tree

malariagen_data/anoph/aim_data.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,24 @@ def plot_aim_heatmap(
254254
gn = np.take(gn, ix_sorted, axis=1)
255255
samples = np.take(samples, ix_sorted, axis=0)
256256

257+
species = aims.split("_vs_")
258+
257259
# Set up colors for genotypes
258260
if palette is None:
259261
if self._aim_palettes is None:
260262
raise RuntimeError(
261-
"AIM palettes have not been configured. "
262-
"Please provide a 'palette' parameter or configure AIM_PALETTES."
263+
"AIM palettes are not available for this data resource. "
264+
"Please provide the 'palette' parameter explicitly (4 colors)."
263265
)
264266
palette = self._aim_palettes[aims]
265267
if len(palette) != 4:
266268
raise RuntimeError(
267-
f"Expected AIM palette to have 4 colors, got {len(palette)}"
269+
"Expected AIM palette to have 4 colors "
270+
f"(missing, {species[0]}/{species[0]}, {species[0]}/{species[1]}, {species[1]}/{species[1]}), "
271+
f"got {len(palette)}"
268272
)
269273
# Expect 4 colors, in the order:
270274
# missing, hom taxon 1, het, hom taxon 2
271-
species = aims.split("_vs_")
272275

273276
# Create subplots.
274277
fig = go_make_subplots(

malariagen_data/anoph/cnv_frq.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,8 @@ def _gene_cnv_frequencies_advanced(
599599
else:
600600
if nobs_mode != "fixed":
601601
raise RuntimeError(
602-
f"Internal error: expected nobs_mode='fixed', "
603-
f"got {nobs_mode!r}"
602+
f"Internal error: expected nobs_mode='fixed', got {nobs_mode!r}. "
603+
"This should not happen; please open a GitHub issue."
604604
)
605605
nobs[:, cohort_index] = cohort.size
606606

malariagen_data/anoph/h1x.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,13 +405,14 @@ def _moving_h1x(ha, hb, size, start=0, stop=None, step=None):
405405

406406
if ha.ndim != 2 or hb.ndim != 2:
407407
raise ValueError(
408-
f"Expected ha and hb to be 2-dimensional, "
409-
f"got ha.ndim={ha.ndim} and hb.ndim={hb.ndim}"
408+
"Expected both haplotype arrays to be 2-dimensional "
409+
"(n_variants, n_haplotypes), "
410+
f"got ndim=({ha.ndim}, {hb.ndim})"
410411
)
411412
if ha.shape[0] != hb.shape[0]:
412413
raise ValueError(
413-
f"ha and hb must have the same number of variants, "
414-
f"got ha.shape[0]={ha.shape[0]} and hb.shape[0]={hb.shape[0]}"
414+
"Expected both haplotype arrays to have the same number of variants "
415+
f"(axis 0), got ({ha.shape[0]}, {hb.shape[0]})"
415416
)
416417

417418
# Construct moving windows.

malariagen_data/anoph/sample_metadata.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,15 @@ def _parse_aim_metadata(
595595
self, sample_set: str, data: Union[bytes, Exception]
596596
) -> pd.DataFrame:
597597
if self._aim_metadata_columns is None:
598-
raise RuntimeError("AIM metadata columns have not been configured.")
598+
raise RuntimeError(
599+
"Internal error: AIM metadata columns are not configured. "
600+
"This should not happen; please open a GitHub issue."
601+
)
599602
if self._aim_metadata_dtype is None:
600-
raise RuntimeError("AIM metadata dtype has not been configured.")
603+
raise RuntimeError(
604+
"Internal error: AIM metadata dtypes are not configured. "
605+
"This should not happen; please open a GitHub issue."
606+
)
601607
if isinstance(data, bytes):
602608
# Parse CSV data but don't apply the dtype yet.
603609
df = pd.read_csv(io.BytesIO(data), na_values="")

malariagen_data/util.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,21 +1580,25 @@ def _apply_allele_mapping(x, mapping, max_allele):
15801580

15811581
def _dask_apply_allele_mapping(v, mapping, max_allele):
15821582
if not isinstance(v, da.Array):
1583-
raise TypeError(f"Expected v to be a dask.array.Array, got {type(v).__name__}")
1583+
raise TypeError(
1584+
f"Expected input array to be a dask.array.Array, got {type(v).__name__}"
1585+
)
15841586
if not isinstance(mapping, np.ndarray):
15851587
raise TypeError(
15861588
f"Expected mapping to be a numpy.ndarray, got {type(mapping).__name__}"
15871589
)
15881590
if v.ndim != 2:
1589-
raise ValueError(f"Expected v to be 2-dimensional, got {v.ndim} dimensions")
1591+
raise ValueError(
1592+
f"Expected input array to be 2-dimensional, got {v.ndim} dimensions"
1593+
)
15901594
if mapping.ndim != 2:
15911595
raise ValueError(
15921596
f"Expected mapping to be 2-dimensional, got {mapping.ndim} dimensions"
15931597
)
15941598
if v.shape[0] != mapping.shape[0]:
15951599
raise ValueError(
1596-
f"v and mapping must have same first dimension, "
1597-
f"got v.shape[0]={v.shape[0]} and mapping.shape[0]={mapping.shape[0]}"
1600+
"Expected input array and mapping to have the same first dimension, "
1601+
f"got {v.shape[0]} and {mapping.shape[0]}"
15981602
)
15991603
v = v.rechunk((v.chunks[0], -1))
16001604
mapping = da.from_array(mapping, chunks=(v.chunks[0], -1))
@@ -1619,33 +1623,39 @@ def _genotype_array_map_alleles(gt, mapping):
16191623
f"Expected mapping to be a numpy.ndarray, got {type(mapping).__name__}"
16201624
)
16211625
if gt.ndim != 3:
1622-
raise ValueError(f"Expected gt to be 3-dimensional, got {gt.ndim} dimensions")
1626+
raise ValueError(
1627+
f"Expected genotype calls array to be 3-dimensional, got {gt.ndim} dimensions"
1628+
)
16231629
if mapping.ndim != 3:
16241630
raise ValueError(
16251631
f"Expected mapping to be 3-dimensional, got {mapping.ndim} dimensions"
16261632
)
16271633
if gt.shape[0] != mapping.shape[0]:
16281634
raise ValueError(
1629-
f"gt and mapping must have same first dimension, "
1630-
f"got gt.shape[0]={gt.shape[0]} and mapping.shape[0]={mapping.shape[0]}"
1635+
"Expected genotype calls array and mapping to have the same first dimension, "
1636+
f"got {gt.shape[0]} and {mapping.shape[0]}"
16311637
)
16321638
if gt.shape[1] <= 0:
1633-
raise ValueError(f"Expected gt.shape[1] > 0, got {gt.shape[1]}")
1639+
raise ValueError(f"Expected genotype calls axis 1 to be > 0, got {gt.shape[1]}")
16341640
if gt.shape[2] != 2:
1635-
raise ValueError(f"Expected gt.shape[2] == 2 (diploid), got {gt.shape[2]}")
1641+
raise ValueError(
1642+
f"Expected genotype calls axis 2 to be 2 (diploid), got {gt.shape[2]}"
1643+
)
16361644
if gt.size > 0:
16371645
# Block is not empty, can pass through to GenotypeArray.
16381646
if gt.shape[0] <= 0:
16391647
raise RuntimeError(
1640-
f"Internal error: gt.size > 0 but gt.shape[0] = {gt.shape[0]}"
1648+
f"Internal error: non-empty genotype block but axis 0 is {gt.shape[0]}. "
1649+
"Please open a GitHub issue."
16411650
)
16421651
m = mapping[:, 0, :]
16431652
out = allel.GenotypeArray(gt).map_alleles(m).values
16441653
else:
16451654
# Block is empty so no alleles need to be mapped.
16461655
if gt.shape[0] != 0:
16471656
raise RuntimeError(
1648-
f"Internal error: gt.size == 0 but gt.shape[0] = {gt.shape[0]}"
1657+
f"Internal error: empty genotype block but axis 0 is {gt.shape[0]}. "
1658+
"Please open a GitHub issue."
16491659
)
16501660
out = gt
16511661
return out

0 commit comments

Comments
 (0)