Summary
Bare except: clause in compare.py swallows KeyboardInterrupt, SystemExit, and GeneratorExit along with every unrelated bug. It also silently empties the wealth-decile impact blocks, hiding real regressions in the underlying calculation.
Location
policyengine_api/endpoints/economy/compare.py:816
What goes wrong
try:
wealth_decile_impact_data = wealth_decile_impact(baseline, reform)
intra_wealth_decile_impact_data = intra_wealth_decile_impact(
baseline, reform
)
except:
wealth_decile_impact_data = {}
intra_wealth_decile_impact_data = {}
- A bare
except: catches BaseException, including signals (KeyboardInterrupt) and interpreter shutdown (SystemExit). Workers become harder to terminate cleanly.
- Any exception — a genuine
ZeroDivisionError in the calculation, an attribute error from a model upgrade, etc. — is silently replaced with empty dicts, so downstream consumers see "no wealth decile data" instead of an error.
Suggested fix
except Exception:
logging.exception("wealth_decile_impact failed")
wealth_decile_impact_data = {}
intra_wealth_decile_impact_data = {}
Narrow further to the specific exception types that are expected (e.g. KeyError, ValueError) if possible.
Severity
Low.
Summary
Bare
except:clause incompare.pyswallowsKeyboardInterrupt,SystemExit, andGeneratorExitalong with every unrelated bug. It also silently empties the wealth-decile impact blocks, hiding real regressions in the underlying calculation.Location
policyengine_api/endpoints/economy/compare.py:816What goes wrong
except:catchesBaseException, including signals (KeyboardInterrupt) and interpreter shutdown (SystemExit). Workers become harder to terminate cleanly.ZeroDivisionErrorin the calculation, an attribute error from a model upgrade, etc. — is silently replaced with empty dicts, so downstream consumers see "no wealth decile data" instead of an error.Suggested fix
Narrow further to the specific exception types that are expected (e.g.
KeyError,ValueError) if possible.Severity
Low.