Add log_and_raise helper to merge fre_logger.error and raise steps#831
Add log_and_raise helper to merge fre_logger.error and raise steps#831
log_and_raise helper to merge fre_logger.error and raise steps#831Conversation
log_and_raise helper to merge fre_logger.error and raise steps
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #831 +/- ##
==========================================
+ Coverage 84.12% 84.35% +0.23%
==========================================
Files 71 71
Lines 4944 4974 +30
==========================================
+ Hits 4159 4196 +37
+ Misses 785 778 -7
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
@copilot find other locations |
Done in commit
|
|
@copilot updating the |
Investigated CI failures in commit Root cause: replacing Fix: added |
… patterns Agent-Logs-Url: https://github.com/NOAA-GFDL/fre-cli/sessions/98852929-27ab-48b1-8b84-1787a26e72f3 Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
Agent-Logs-Url: https://github.com/NOAA-GFDL/fre-cli/sessions/98852929-27ab-48b1-8b84-1787a26e72f3 Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
Replace bare raise ExcType(msg) statements with log_and_raise(msg, ExcType) calls, which logs the error before raising. This ensures all raised exceptions are consistently logged via fre_logger.error. Changes: - Add 'from fre import log_and_raise' imports where missing - Convert raise ValueError/TypeError/FileNotFoundError/FileExistsError/ IOError/RuntimeError/OSError/Exception/NotImplementedError/KeyError/ NameError to log_and_raise equivalents - For 'raise ExcType(msg) from exc' patterns, use log_and_raise(msg, ExcType, exc=exc) - For patterns where fre_logger.error + raise had the same message, collapse into single log_and_raise call - For patterns where fre_logger.error + raise had different messages, keep fre_logger.error and replace raise with log_and_raise - Preserve all bare re-raises (raise with no arguments) - Preserve NotImplementedError in abstract methods in timeAverager.py - Collapse multi-line raise statements into single log_and_raise calls - Convert multi-argument ValueError to single string message log_and_raise calls Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
Make exception type explicit in all log_and_raise calls where ValueError was being raised (matching the original raise ValueError statements). Also fix a code structure issue in combine.py where the if/elif frequency blocks were incorrectly nested. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
…cit ValueError to log_and_raise calls - Restore accidentally removed interval_object = duration_parser.parse(interval) in combine.py form_bronx_directory_name() - Add explicit ValueError type to all log_and_raise() calls that relied on the default parameter: frenctoolsTimeAverager.py, generate_time_averages.py, wrapper.py, mask_atmos_plevel.py, platformfre.py, targetfre.py, cmor_yamler.py Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
Replace all raise ExcType(msg) and raise ExcType(msg) from exc patterns with log_and_raise(msg, ExcType) and log_and_raise(msg, ExcType, exc=exc) respectively, across: - fre/pp/configure_script_yaml.py (already had import) - fre/cmor/cmor_helpers.py (already had import) - fre/cmor/cmor_mixer.py (already had import) - fre/cmor/cmor_finder.py (added import) - fre/cmor/cmor_config.py (added import) - fre/yamltools/helpers.py (added import) - fre/yamltools/info_parsers/cmor_info_parser.py (added import) - fre/yamltools/info_parsers/compile_info_parser.py (added import) - fre/yamltools/info_parsers/analysis_info_parser.py (added import) - fre/yamltools/info_parsers/pp_info_parser.py (added import) - fre/yamltools/combine_yamls_script.py (added import) Also converts printf-style multi-arg ValueError/FileNotFoundError calls to f-string log_and_raise equivalents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
…ed-before-assignment errors Agent-Logs-Url: https://github.com/NOAA-GFDL/fre-cli/sessions/6e92661a-f061-4b23-a675-7ddeb69b0a21 Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
05ea559 to
5cf50b1
Compare
Replace fre_logger.error with fre_logger.exception for better error logging.
|
@copilot this is subtle, make sure this jives with |
…traceback tests Per Python logging best practices (PEP 282, logging HOWTO): - Use exc_info=True (not logger.exception) for caught exception tracebacks - Use stack_info=True to always include call-site stack trace in log output - Both ensure Traceback info reaches log files set up via fre -l New tests verify that when a FileHandler is attached (simulating fre -l ./logger_output.log): - stack trace appears in log file for simple raises (stack_info=True) - caught exception traceback appears in log file for chained raises (exc_info=True) Agent-Logs-Url: https://github.com/NOAA-GFDL/fre-cli/sessions/73b3875d-4130-4999-9488-0dc773ca1c45 Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
Agent-Logs-Url: https://github.com/NOAA-GFDL/fre-cli/sessions/73b3875d-4130-4999-9488-0dc773ca1c45 Co-authored-by: ilaflott <6273252+ilaflott@users.noreply.github.com>
Done in
Two new tests (
|
| pytest.fail("expected log record not found") | ||
|
|
||
|
|
||
| def test_log_and_raise_stack_trace_in_log_file(tmp_path): |
There was a problem hiding this comment.
this isn't the right testing approach- the logfile behavior is more for the CLI:
fre -l logger_output.log ... and so one should use click's CliRunner
Describe your changes
Adds a
log_and_raise()helper tofre/__init__.pythat combinesfre_logger.error()andraiseinto a single call, eliminating repetitive and duplicated error text across the codebase. Allraise ExcType(msg)statements throughout the codebase have been converted to use this helper.Helper function (
fre/__init__.py):-> NoReturnso pylint and type checkers treat calls to it as control flow terminators (just likeraise)fre_loggerwithstacklevel=2so log output attributes the correct caller, notlog_and_raiseitselfstack_info=Trueso the call-site stack trace appears in every configured handler, including log files set up viafre -lexc_info=Truewhenexcis provided, per the Python logging HOWTO, so the caught exception's full traceback is written to every handlerexc_type(defaultValueError) with the same messageexcparam (raise ... from exc)Conversion patterns applied across ~44 files:
raise ExcType(msg)→log_and_raise(msg, ExcType)raise ExcType(msg) from exc→log_and_raise(msg, ExcType, exc=exc)fre_logger.errorand replaced both withlog_and_raisefre_logger.errorfor context, replaced raise withlog_and_raiseraise(no-arg re-raises in except blocks) — left unchangedraise NotImplementedError()intimeAverager.py— left unchangedTraceback logging for
fre -llog files:A key motivation for this helper is ensuring
Tracebackinfo reaches log files specified viafre -l ./logger_output.log. Per Python logging best practices (PEP 282, logging HOWTO):stack_info=Trueis always passed, so the call-site stack trace (Stack (most recent call last):) appears in every handlerexc_info=Trueis passed whenexcis given, so the caught exception's traceback (Traceback (most recent call last):) appears in every handlerTwo new tests (
test_log_and_raise_stack_trace_in_log_file,test_log_and_raise_traceback_in_log_file) simulatefre -l ./logger_output.logby attaching aFileHandlerand verify:Files converted (representative list):
app/helpers.py,app/remap_pp_components/,app/mask_atmos_plevel/,app/generate_time_averages/,app/regrid_xy/,pp/checkout_script.py,pp/run_script.py,pp/trigger_script.py,pp/nccheck_script.py,pp/status_script.py,pp/histval_script.py,pp/rename_split_script.py,pp/split_netcdf_script.py,pp/ppval_script.py,pp/validate_script.py,pp/install_script.py,pp/configure_script_yaml.py,make/(multiple files),make/gfdlfremake/(multiple files),cmor/cmor_helpers.py,cmor/cmor_mixer.py,cmor/cmor_finder.py,cmor/cmor_config.py,cmor/cmor_yamler.py,yamltools/(multiple files),run/frerun.py,check/frecheck.pyIssue ticket number and link (if applicable)
Checklist before requesting a review