From 7a7bd758a4f9fbdfe97d8100ea93c4d1bc334882 Mon Sep 17 00:00:00 2001 From: Markus Hilger Date: Tue, 1 Sep 2026 23:52:49 +0200 Subject: [PATCH] Let a failed request report itself Two places where the code that exists to explain a failure fails instead, and the caller is shown the second failure rather than the first. _do_web_request builds its message from the response body when that body is not the JSON error document the spec asks for. An html 404 page is exactly that, the body is bytes, and str + bytes raised TypeError. The status and the body never reached anyone. LenovoFirmwareConfig raised a bare Exception when python-lxml and python-eficompressor are absent. Confluent has no handler for one, so a missing dependency showed as "Unexpected Error" and hid a message that already said what to install. Neither changes what fails, only what the caller is told. --- confluent_server/aiohmi/ipmi/oem/lenovo/config.py | 8 ++++++-- confluent_server/aiohmi/redfish/oem/generic.py | 9 ++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/confluent_server/aiohmi/ipmi/oem/lenovo/config.py b/confluent_server/aiohmi/ipmi/oem/lenovo/config.py index 7ae16c66..35e72d3b 100644 --- a/confluent_server/aiohmi/ipmi/oem/lenovo/config.py +++ b/confluent_server/aiohmi/ipmi/oem/lenovo/config.py @@ -147,8 +147,12 @@ def _eval_conditional(expression, cfg, setting): class LenovoFirmwareConfig(object): def __init__(self, xc, useipmi=True): if not etree: - raise Exception("python-lxml and python-eficompressor required " - "for this function") + # Not a bare Exception. Confluent has no handler for one, so a + # missing optional dependency showed as "Unexpected Error" and hid + # the message below, which already names what to install. + raise pygexc.UnsupportedFunctionality( + "python-lxml and python-eficompressor required " + "for this function") if useipmi: self.connection = xc.ipmicmd else: diff --git a/confluent_server/aiohmi/redfish/oem/generic.py b/confluent_server/aiohmi/redfish/oem/generic.py index b44bc253..ba739fb4 100644 --- a/confluent_server/aiohmi/redfish/oem/generic.py +++ b/confluent_server/aiohmi/redfish/oem/generic.py @@ -1794,7 +1794,14 @@ class OEMHandler(object): errmsg = ','.join(errmsg) raise exc.RedfishError(errmsg) except (ValueError, KeyError): - raise exc.PyghmiException(str(url) + ":" + res[0]) + # Reached by an html 404 page, or anything else that is not + # the JSON error document. res[0] is bytes there, so building + # the message crashed and the caller saw that TypeError + # instead of the status and the body. + body = res[0] + if isinstance(body, bytes): + body = body.decode('utf-8', errors='replace') + raise exc.PyghmiException('{0}:{1}'.format(url, body)) if payload is None and method is None: self._urlcache[url] = { 'contents': res[0],