Upstream widened the except in close_all_tabs_except to catch
NoSuchWindowException; this branch had rewritten the same two lines from print
to logging. Both are wanted, so the resolution keeps the wider except and the
logger call, and takes the new import.
Claude-Session: https://claude.ai/code/session_01RCncv1HC4UvoJcYqBtwxrt
Follow-ups from running the conversion against a live account.
Tab open/close bookkeeping moves from info to debug. It was 19 of the 33
records in a full run, so the six task outcomes that are the point of the
summary were outnumbered three to one by tab handles and query strings. The
"could not close" case stays at warning, a tab that will not close is a real
problem rather than bookkeeping.
The [FAIL] summary moves into log_utils.exception_summary, which takes the
first line, drops the "(Session info: ...)" fragment and caps the result. A
selenium exception embeds the whole msedgedriver stacktrace in str(), and the
cap means a pathological message cannot push a screenful of text into one
record. The cut marker is ASCII because this can land on a Windows console
whose encoding cannot represent an ellipsis.
The suppressed-library list was checked rather than guessed: with the root
logger wide open, a real browser session plus one ollama call produced records
from httpx, httpcore, urllib3 and selenium only, and nothing else. That set is
already pinned. Worth noting selenium alone emits 45 records for a single page
load, so without the pinning the debug mode this PR recommends for bug reports
would be unusable.
Closes#14.
The runtime modules now log through the stdlib logging module. A new
log_utils.setup_logging is called once from main.py, and each module holds
its own logging.getLogger(__name__) so every line says which module it came
from.
The [INFO] and [WARNING] prefixes are gone, since the level field carries
that now. [OK], [SKIP] and [FAIL] stay in the message text: they are the
per-task outcome summary from complete_all_tasks rather than severities, and
folding them into the level would erase the run summary. They map to info,
warning and error, which is the one thing print could not express, a real
failure now sorts above a task the current UI variant simply does not ship.
Two things fall out of having levels at all:
- REWARDS_FARMER_LOG_LEVEL=DEBUG attaches the traceback to every [FAIL],
which is the stack trace that bug reports keep having to be asked for.
- REWARDS_FARMER_LOG_FILE writes the same output to a file, so an unattended
run can be read after the fact.
Both are off by default, so a normal run looks the same as before apart from
the timestamp and level columns.
The [FAIL] summary keeps only the first line of the exception message. A
selenium exception carries the whole msedgedriver stacktrace inside str(),
tens of lines of it, which would turn one task into one screenful and make
the log file impossible to scan. The full detail is still there with the
traceback on debug.
The console stream is stdout rather than the StreamHandler default of stderr,
so anyone already redirecting stdout keeps getting the output there, and its
error handler is set to replace. Card descriptions are scraped from the page
and are not ASCII outside the en-US market, and the Windows console encoding
raises on them.
check_selectors.py, fitts_law.py and analyze_keypresses.py are left on print.
Their output is formatted report text, and prefixing every row of a
diagnostic table with a timestamp and a level makes it harder to read.