If base_url has no scheme (for example TraceClient("trace.example.org", "app", key="k")), the sender thread dies on the first report and prints a traceback to the host program's stderr.
In trace_client/trace_client.py, _send() builds urllib.request.Request(...) before its try block. Request.__init__ parses the URL and raises ValueError: unknown url type: 'trace.example.org/api/metrics'. Nothing in _drain() catches that, so the daemon thread exits and threading's default excepthook writes the full traceback to stderr. Reproduced on Python 3.8.10:
Exception in thread trace-client/app:
Traceback (most recent call last):
...
File ".../trace_client/trace_client.py", line 184, in _send
request = urllib.request.Request(
...
ValueError: unknown url type: 'trace.example.org/api/metrics'
This breaks the documented promise that failures "are logged at DEBUG on the trace logger and otherwise not at all". Once the thread is dead, later reports also just fill the queue and get dropped.
Suggested fix: build the Request inside the existing try in _send(), so a malformed URL is logged at DEBUG as could not deliver and the thread keeps running. The constructor's behaviour stays the same: it does not start raising for URLs it used to accept.
This issue was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson
If
base_urlhas no scheme (for exampleTraceClient("trace.example.org", "app", key="k")), the sender thread dies on the first report and prints a traceback to the host program's stderr.In
trace_client/trace_client.py,_send()buildsurllib.request.Request(...)before itstryblock.Request.__init__parses the URL and raisesValueError: unknown url type: 'trace.example.org/api/metrics'. Nothing in_drain()catches that, so the daemon thread exits andthreading's default excepthook writes the full traceback to stderr. Reproduced on Python 3.8.10:This breaks the documented promise that failures "are logged at DEBUG on the
tracelogger and otherwise not at all". Once the thread is dead, later reports also just fill the queue and get dropped.Suggested fix: build the
Requestinside the existingtryin_send(), so a malformed URL is logged at DEBUG ascould not deliverand the thread keeps running. The constructor's behaviour stays the same: it does not start raising for URLs it used to accept.This issue was drafted during a Gardener session (https://github.com/Stephenson-Software/gardener).
drafted by Claude on behalf of Daniel Stephenson