Surface auth failures when saving a command - #160
Merged
Merged
Conversation
requests does not raise on a 4xx, and save_command never checked the status code, so the 401/403 branch was unreachable. An expired token silently dropped every command with nothing recorded — the client looked like it was working while saving nothing. Adding raise_for_status makes the existing handler reachable, matching what search and get_status_view already do. 5xx stays quiet on purpose. This runs on every shell command, so a transient server error must not write on every prompt. Note on where this surfaces: the shell hook backgrounds the save and redirects it to ~/.bashhub/log.txt (lib-bashhub.sh:67), so this makes the failure diagnosable in the log rather than visible in the terminal. Making an expired token visible the way missing config already is would need a separate once-per-session notification. test_bashhub_save assigned rest_client.save_command directly and never restored it, leaving the stub in place for every later test in the run, which these tests would otherwise pick up. It now uses monkeypatch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
save_commandnever checked the response status, so a rejected auth token was swallowed silently and every command was dropped with nothing recorded anywhere.The bug
requestsdoes not raise on a 4xx, andsave_commandcalledrequests.postwithoutraise_for_status(). Theexcept Exceptionblock that checks for 401/403 was therefore unreachable for HTTP errors — nothing ever raised to reach it.Confirmed by mocking a 401 response: the call printed nothing and returned normally. An expired token means the client looks like it is working while saving nothing, indefinitely.
searchandget_status_viewget this right by accident — their.json()parsing throws on an error body, which reaches the handler.save_commandhad no such accident.The change
r = requests.post(url, data=command.to_JSON(), headers=json_auth_headers()) + r.raise_for_status() except ConnectionError: print("Sorry, looks like there's a connection error") - pass except Exception: if r is not None and r.status_code in (403, 401): print("Permissions Issue. Run bashhub setup to re-login.")raise_for_status()makes the existing handler reachable, matching what the other endpoints already do.5xx stays quiet on purpose. This runs on every shell command, so a transient server error must not write on every prompt. Only 401/403 — which are persistent and actionable — produce output.
Where this actually surfaces
Worth knowing before reviewing: this makes the failure diagnosable in the log, not visible in the terminal.
The shell hook backgrounds the save and redirects it, at
lib-bashhub.sh:67:__bh_process_command(lines 77–107) is wherebashhub saveruns, so both stdout and stderr go to~/.bashhub/log.txt. Fish does the same atbashhub.fish:73. Verified by simulating the exact construct — the message lands in the log and nothing reaches the terminal.There is a real gap left over.
__bh_check_bashhub_installation(lines 112–139) runs once per session outside the redirect and already prints things like "Missing Bashhub access token. Please run 'bashhub setup' to re-login." — but it only greps the config for the presence ofaccess_token, never whether the server still accepts it. So an expired-but-present token falls between the two: the startup check sees a well-formed config and stays quiet, and the per-command failure goes to a log nobody reads.Closing that would need a separate once-per-session notification (for example,
save_commanddropping a marker file that the session-start check reads and clears). Deliberately not in this PR — printing on every prompt is not an acceptable alternative.Tests
Five tests in
tests/test_rest_client.pycovering 401, 403, success, 5xx-stays-quiet, and connection errors. Revertingraise_for_statusfails the 401 and 403 cases, so they are real regression guards.Note on the test change
tests/test_bashhub.pyhas a one-line change that is a prerequisite, not a drive-by.test_bashhub_saveassignedrest_client.save_commanddirectly and never restored it, leaving the stub live for the rest of the run — the new tests would call the stub instead of the real function and all five would fail. It now usesmonkeypatch, which restores it.That test leaks three
bashhub_globalsvalues the same way, and one of those leaks is load-bearing for another test:test_get_bh_filterasserts onbashhub_globals.BH_FILTER, which is computed once at import and so can never reflect a config written during the test — it passes only because it inherits the leaked'echo'. That is pre-existing on master (it already fails there when run alone or in reverse file order) and is left untouched here to keep this PR to the one fix.Verification
119 passed, mypy clean,
ruff check bashhub/clean.ruff check tests/reports 12 findings on both master and this branch — none added.🤖 Generated with Claude Code