Skip to content

[DT-4058] Update NA exception signature - #3046

Merged
rushtong merged 3 commits into
developfrom
gr-DT-4058-fix-not-authorized-bug
Sep 2, 2026
Merged

[DT-4058] Update NA exception signature#3046
rushtong merged 3 commits into
developfrom
gr-DT-4058-fix-not-authorized-bug

Conversation

@rushtong

@rushtong rushtong commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Addresses

https://broadworkbench.atlassian.net/browse/DT-4058

Summary

Authenticated GET /api/user/me calls return a 500 in BEEs:

{"message":"Primary challenge parameter must not be null.","code":500}

The endpoint works in dev, staging, and prod.

Why only BEEs failed

ECM answers 401 when the user has not accepted the Terms of Service.
NihService.syncAccount expects this and catches NotAuthorizedException. It
cannot catch an NPE, so the NPE reaches Resource.createExceptionResponse,
which has no handler for it and returns a 500.

Tomcat omits the reason phrase by default, so ECM sends HTTP/1.1 401 with an
empty phrase. The two environments then differ:

  • Live environments use the GKE ingress. The Google load balancer rewrites the status line and adds Unauthorized. Consent never sees a null.
  • BEEs use the HAProxy ingress. HAProxy passes the reason phrase through unchanged and adds nothing, so Consent sees a null.

Testing

I have manually tested in a BEE. Steps to reproduce:

  1. Deploy a new DUOS BEE
  2. Update consent's version to point to this branch
  3. Visit the consent swagger page
  4. Authenticate
  5. Hit GET /api/user/me and correctly see a 404
  6. Hit POST /api/user to create an entry for your authenticated account
  7. Revisit GET /api/user/me and see your user information.

Have you read CONTRIBUTING.md lately? If not, do that first.

  • Label PR with a Jira ticket number and include a link to the ticket
  • Label PR with a security risk modifier [no, low, medium, high]
  • PR describes scope of changes
  • Get a minimum of one thumbs worth of review, preferably two if enough team members are available
  • Get PO sign-off for all non-trivial UI or workflow changes
  • Verify all tests go green
  • Test this change deployed correctly and works on dev environment after deployment

rushtong and others added 3 commits September 2, 2026 07:00
A downstream 401 whose status line omits the HTTP reason phrase leaves the
status message null. The previous single-argument call bound that null to the
NotAuthorizedException challenge parameter, which threw
NullPointerException("Primary challenge parameter must not be null.") instead.
Callers that catch NotAuthorizedException could not handle it, so the NPE
reached the resource layer and became a 500.

The second test pins the message. A lone String argument binds to challenge,
not to message, so the old code also dropped the downstream reason phrase from
the exception message.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@rushtong
rushtong marked this pull request as ready for review September 2, 2026 11:43
@rushtong
rushtong requested a review from a team as a code owner September 2, 2026 11:43
@rushtong
rushtong requested review from fboulnois and otchet-broad and a lite review from Copilot and removed request for a team September 2, 2026 11:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is small, directly addresses the reported failure mode, and includes focused tests that would fail under the original NPE behavior.

Pull request overview

Fixes a production-only failure mode where a downstream 401 without an HTTP reason phrase causes HttpClientUtil.handleHttpRequest to throw an unintended NullPointerException, leading to a 500 for authenticated GET /api/user/me in BEEs. The change updates the unauthorized exception construction and adds targeted unit coverage to prevent regressions.

Changes:

  • Update HttpClientUtil.handleHttpRequest to avoid null propagation when translating downstream 401 responses into NotAuthorizedException.
  • Refactor existing caching tests to use assertDoesNotThrow rather than manual try/catch + fail.
  • Add unit tests covering 401 responses with and without an HTTP reason phrase.
File summaries
File Description
src/main/java/org/broadinstitute/consent/http/util/HttpClientUtil.java Adjusts 401 handling to prevent NPE when the downstream status message is null.
src/test/java/org/broadinstitute/consent/http/util/HttpClientUtilTest.java Improves existing tests and adds coverage for 401 responses lacking a reason phrase.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@sonarqubecloud

sonarqubecloud Bot commented Sep 2, 2026

Copy link
Copy Markdown

@fboulnois fboulnois left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@otchet-broad otchet-broad left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@rushtong
rushtong merged commit 5fa524a into develop Sep 2, 2026
12 checks passed
@rushtong
rushtong deleted the gr-DT-4058-fix-not-authorized-bug branch September 2, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants