Skip to content

Commit

Permalink
ENH: make stacked exceptions clearer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffgortmaker committed Dec 26, 2021
1 parent 4bc9521 commit 0f38d82
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 10 deletions.
11 changes: 7 additions & 4 deletions pyblp/configurations/formulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def _build_matrix(

if not fallback:
origin = patsy.origin.Origin(self._formula, 0, len(self._formula))
raise patsy.PatsyError(f"Failed to load data for '{name}'.", origin) from exception
message = f"Failed to load data for '{name}' because of the above exception."
raise patsy.PatsyError(message, origin) from exception

# always have at least one column to represent the size of the data
if not data_mapping:
Expand Down Expand Up @@ -244,7 +245,8 @@ def _build_ids(self, data: Mapping) -> Array:
except Exception as exception:
assert self._absorb is not None
origin = patsy.origin.Origin(self._absorb, 0, len(self._absorb))
raise patsy.PatsyError(f"Failed to load data for '{name}'.", origin) from exception
message = f"Failed to load data for '{name}' because of the above exception."
raise patsy.PatsyError(message, origin) from exception

# build columns of absorbed IDs
ids_columns: List[Array] = []
Expand Down Expand Up @@ -482,7 +484,8 @@ def parse_term_expression(term: patsy.desc.Term) -> sp.Expr:
try:
expression *= parse_expression(factor.name())
except Exception as exception:
raise patsy.PatsyError("Failed to parse a term.", factor.origin) from exception
message = "Failed to parse a term because of the above exception."
raise patsy.PatsyError(message, factor.origin) from exception

return expression

Expand Down Expand Up @@ -542,7 +545,7 @@ def validate_categorical(candidate: sp.Expr, depth: int = 0, categorical: bool =
str(expression)
validate_categorical(expression)
except (TypeError, ValueError) as exception:
raise ValueError(f"The expression '{string}' is malformed.") from exception
raise ValueError(f"The expression '{string}' is malformed because of the above exception.") from exception

# replace patsy functions with the identity function, unless categorical variables are to be explicitly marked
for name in patsy_function_names:
Expand Down
11 changes: 8 additions & 3 deletions pyblp/markets/market.py
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,8 @@ def compute_micro_contributions(
try:
weights = np.asarray(dataset.compute_weights(self.t, self.products, self.agents), options.dtype)
except Exception as exception:
raise RuntimeError(f"Failed to compute weights for micro dataset '{dataset}'.") from exception
message = f"Failed to compute weights for micro dataset '{dataset}' because of the above exception."
raise RuntimeError(message) from exception
shapes = [
(self.I, self.J), (self.I, 1 + self.J), (self.I, self.J, self.J), (self.I, 1 + self.J, self.J),
(self.I, self.J, 1 + self.J), (self.I, 1 + self.J, 1 + self.J)
Expand Down Expand Up @@ -1440,7 +1441,8 @@ def compute_micro_contributions(
try:
values = np.asarray(moment.compute_values(self.t, self.products, self.agents), options.dtype)
except Exception as exception:
raise RuntimeError(f"Failed to compute values for micro moment '{moment}'.") from exception
message = f"Failed to compute values for micro moment '{moment}' because of the above exception."
raise RuntimeError(message) from exception
if values.shape != weights.shape:
raise ValueError(
f"In market {self.t}, micro moment '{moment}' returned an array of shape {values.shape} from "
Expand All @@ -1467,7 +1469,10 @@ def compute_micro_contributions(
moment2.compute_values(self.t, self.products, self.agents), options.dtype
)
except Exception as exception:
raise RuntimeError(f"Failed to compute values for micro moment '{moment2}'.") from exception
message = (
f"Failed to compute values for micro moment '{moment2}' because of the above exception."
)
raise RuntimeError(message) from exception
micro_covariances_numerator[m, m2] = (weighted_values * values2).sum()

return (
Expand Down
3 changes: 2 additions & 1 deletion pyblp/micro.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ def __init__(self, economy: 'Economy', micro_moments: Sequence[MicroMoment]) ->
try:
moment.dataset._validate(economy)
except Exception as exception:
raise ValueError(f"The micro dataset '{moment.dataset}' is invalid.") from exception
message = f"The micro dataset '{moment.dataset}' is invalid because of the above exception."
raise ValueError(message) from exception
for moment2 in micro_moments[:m]:
if moment == moment2:
raise ValueError(f"There is more than one of the micro moment '{moment}'.")
Expand Down
5 changes: 3 additions & 2 deletions pyblp/primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,12 @@ def __new__(
except patsy.PatsyError as exception_j:
if j == 0:
raise exception
raise ValueError(
message = (
f"Each demographic must either be a single column or have a column for each of the "
f"maximum of {max_J} products. There is at least one missing demographic for product "
f"index {j}."
) from exception_j
)
raise ValueError(message) from exception_j
else:
demographics_by_product.append(demographics_j)

Expand Down

0 comments on commit 0f38d82

Please sign in to comment.