Problem
Failures in OSHConnect are reported inconsistently, and the library's diagnostics leak into the host application's logging config. #42 was one instance (a swallowed POST failure surfacing later as an unrelated AttributeError); #43, #44, and #45 are three more found in the same pass. They share root causes worth fixing as a set rather than one-off.
Current state, measured on main:
| Symptom |
Count |
Where |
Bare raise Exception(...) — callers can't catch selectively |
5 |
resources/system.py ×4, resources/datastream.py ×1 |
Log calls on the root logger (logging.warning(...)) |
24 across 6 modules |
resources/base.py (14), system.py, datastream.py, controlstream.py, oshconnectapi.py, events/handler.py |
Modules with a proper logging.getLogger(__name__) |
2 |
csapi4py/mqtt.py, csapi4py/nats.py |
Failed HTTP returning None with no signal |
≥1 |
node.py:338 (discover_systems) |
The consequence for downstreams (OSHConnectBroker-Py hit all of these): you cannot except OSHConnectError around a sync loop, you cannot silence or route OSHConnect's logging without touching the root logger, and a failed discovery is indistinguishable from an empty server.
Scope
Sub-issues track the individual pieces. This issue is the umbrella — close it when they're all done.
Not in scope: changing which operations fail (only how failures are reported), and rewriting the api_helpers.py free-function layer, which intentionally returns raw requests.Response.
Compatibility
Any new exception type should subclass Exception so existing except Exception: callers keep working. The logging changes are additive — a library that stops writing to the root logger only affects apps that were relying on that leak.
Problem
Failures in OSHConnect are reported inconsistently, and the library's diagnostics leak into the host application's logging config. #42 was one instance (a swallowed POST failure surfacing later as an unrelated
AttributeError); #43, #44, and #45 are three more found in the same pass. They share root causes worth fixing as a set rather than one-off.Current state, measured on
main:raise Exception(...)— callers can't catch selectivelyresources/system.py×4,resources/datastream.py×1logging.warning(...))resources/base.py(14),system.py,datastream.py,controlstream.py,oshconnectapi.py,events/handler.pylogging.getLogger(__name__)csapi4py/mqtt.py,csapi4py/nats.pyNonewith no signalnode.py:338(discover_systems)The consequence for downstreams (OSHConnectBroker-Py hit all of these): you cannot
except OSHConnectErroraround a sync loop, you cannot silence or route OSHConnect's logging without touching the root logger, and a failed discovery is indistinguishable from an empty server.Scope
Sub-issues track the individual pieces. This issue is the umbrella — close it when they're all done.
Not in scope: changing which operations fail (only how failures are reported), and rewriting the
api_helpers.pyfree-function layer, which intentionally returns rawrequests.Response.Compatibility
Any new exception type should subclass
Exceptionso existingexcept Exception:callers keep working. The logging changes are additive — a library that stops writing to the root logger only affects apps that were relying on that leak.