Repository navigation
[AI-3363] Log the server's error code and bearer expiry on every 401 - #1232
Conversation
The handler must sit inside SignalR's token handler to see the bearer it sent, so it is installed through HttpMessageHandlerFactory rather than wrapped around the client. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR Summary by QodoReport bearer rejection details for daemon and watcher 401s
AI Description
Diagram
High-Level Assessment
Files changed (7)
|
Code Review by Qodo
1.
|
Over HTTP/1.1 SignalR opens the WebSocket outside every message handler, so the hubs take a WebSocket factory that records the upgrade's 401. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit 7ba0575 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit c5107cd |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit d27bd54 |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
/agentic_review |
|
Code review by qodo was updated up to the latest commit d0b941e |
AI-3363 (no GitHub issue)
What & why
The daemon and watcher log a 401 as a bare status, so a refused bearer cannot be told apart from a lapsed one without the server's log. A new
BearerRejectionReportHandlerreports every 401 with the server'serrorcode and the refused bearer's subject, issue time and expiry against local time — never the bearer or the query string — and leaves the response untouched. It is installed on the daemon's hub, the daemon's agent-run event queue, and the watcher's hub.Where to look
The hubs install it through
HttpMessageHandlerFactory, which places it inside SignalR's own token handler; that is what lets it see the bearer SignalR sent. The body is buffered (capped at 4 KiB) so a caller can still read it.Verification
A SignalR client against a stub server answering negotiate with a 401 reports
invalid_tokenand the subject of the bearer the token provider supplied, proving the placement. Unit tests pin the report for an expired bearer, no bearer, and an unreadable body or token; that other statuses report nothing; and that the caller still reads the body.JwtClaims.TryGetTimeis pinned for numeric, non-numeric and out-of-range claims. Release AOT publish of the CLI and daemon shows no trim or AOT warnings.🤖 Generated with Claude Code