Repository navigation
[18.0][IMP] report_py3o: improve error observability in LO conversion chain - #1166
Conversation
fsmw
left a comment
There was a problem hiding this comment.
Thanks @rrebollo for the reciprocal review opportunity — happy to return the favor on #1165.
Solid PR. Confirmed the controller pattern matches report_csv (line 107) and report_xlsx (line 101) exactly: logger.exception before serialize_exception. Good catch on the missing os.path.exists check — that's the real root cause of the silent LO exit-0-with-no-output chain (we hit a similar issue once with HTML content in templates).
The RuntimeError → UserError change is also correct and the existing test_py3o_report_availability already covers that path at line 264.
CI all green (pre-commit, Odoo, OCB, codecov, runboat), tests are appropriately focused (TransactionCase for the model path, HttpCase + assertLogs for the controller), and the localized error messages + stderr context in logger.error are exactly what admins need for postmortem.
Approved ✅
|
There hasn't been any activity on this pull request in the past 4 months, so it has been marked as stale and it will be closed automatically if no further activity occurs in the next 30 days. |
0a0142a to
94c3cab
Compare
|
Review comments addressed — thanks @vvrossem for the detailed pass. Resolved the threads where the suggestion was applied as-is; left replies on the three where we took a small liberty (self.env._ for the new translated string, both logs kept, and Two extra notes: the module-level |
|
The message of the second commit mentions an indentation fix in |
94c3cab to
10c01f4
Compare
|
@vvrossem both points addressed: the |
LibreOffice can exit with a zero status while producing no output file (e.g. when the rendered ODT contains content it cannot handle). The previous code blindly opened the expected output path, so the failure surfaced as an unhandled FileNotFoundError far from its root cause. Convert subprocess.check_output failures into a UserError with an actionable message, capture LO stdout+stderr for the logs, and verify the output file exists before using it. Log the error before raising when the conversion command itself cannot be executed. Controller: add logger.exception() before serializing the error to JSON, so the real traceback appears in the Odoo logs instead of being silently swallowed by the except Exception clause. Log the request URL rather than reportname, which may be unbound if the URL cannot be parsed. Tests: cover the zero-exit-no-output branch, the failing conversion command and the controller logging path; update the availability test to expect UserError. Also switch the strings touched here to the Odoo 18 self.env._() API and drop the now-unused module-level `_` imports. Backward compatibility note: _convert_single_report_cmd now raises UserError instead of RuntimeError when the LibreOffice runtime is not available, which is a behavior change on a stable branch. Overrides catching RuntimeError must be updated. Follows OCA patterns from report_csv, report_xlsx, report_xml controllers for consistent error logging across the reporting-engine ecosystem.
10c01f4 to
3cf9958
Compare
|
@vvrossem, your suggestions have been addressed. Would you be so kind as to review this one again? |
|
This PR has the |
|
@legalsylvain could you merge this one? |
|
@legalsylvain if you don't mind, I'm going to merge this. |
|
@jelenapoblet would you finally merge this one please? |
jelenapoblet
left a comment
There was a problem hiding this comment.
This PR fixes error handling and logging, it doesn’t add a new feature and it has neccesary reviews. I'll proceed to merge
|
/ocabot merge patch |
|
This PR looks fantastic, let's merge it! |
|
Congratulations, your PR was merged at b5f21a8. Thanks a lot for contributing to OCA. ❤️ |
Problem
When LibreOffice fails to convert a rendered ODT to the target format,
FileNotFoundErrorpropagates unhandled, the controller catches it without logging, and debugging is impossible.Actual production traceback (anonymized):
The
FileNotFoundErroris not the root cause — it is the last symptom of a silent failure chain:--headless --convert-to→ exit code 0 → but silently produces no output file (e.g. because the rendered ODT contains HTML content LO cannot handle)_convert_single_reporthas zero error handling —subprocess.check_outputsucceeds, code computes the expected output path, never verifies the file existscreate_reporttriesopen(result_path, "r+b")→FileNotFoundErrorpropagatesexcept Exceptiondoes not log — the entire traceback is silently swallowed, returned as JSON to the browser, and lost on page refreshFix
Two minimal changes following OCA patterns already used by sibling addons (
report_csv,report_xlsx,report_xml):py3o_report.py— Model-level error handling:subprocess.check_output(..., stderr=subprocess.STDOUT)try/except FileNotFoundError→UserErrortry/except CalledProcessError→logger.error(details)+UserErroros.path.exists(result_path)→logger.error(stderr)+UserErrorif missing_convert_single_report_cmd:RuntimeError→UserErrorcontrollers/main.py— Controller-level logging (one line):logger.exception("Error while generating py3o report: %s", reportname)beforeserialize_exceptionreport_csv,report_xlsx,report_xmlcontrollers exactlyTesting
Two new tests added:
test_convert_single_report_called_process_errorTransactionCase+mock.patch("subprocess.check_output")_convert_single_reportraisesUserErroron LO failureTestReportPy3oController.test_report_download_error_loggingHttpCase+mock.patch.object(ReportController, "report_routes")+assertLogs@BinhexTeam T18747