Improve error message for invalid client in org context#3169
Improve error message for invalid client in org context#3169ThaminduR wants to merge 1 commit intowso2-extensions:masterfrom
Conversation
Return a more descriptive error message when an OAuth client is not found in an organization context, instead of the generic "Invalid Client" message. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| tokenRespDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT); | ||
| tokenRespDTO.setErrorMsg("Invalid Client"); | ||
| String errorMessage = "Invalid Client"; |
There was a problem hiding this comment.
Log Improvement Suggestion No: 1
| tokenRespDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT); | |
| tokenRespDTO.setErrorMsg("Invalid Client"); | |
| String errorMessage = "Invalid Client"; | |
| tokenRespDTO.setErrorCode(OAuth2ErrorCodes.INVALID_CLIENT); | |
| log.error("Invalid client detected. Error code: {}", OAuth2ErrorCodes.INVALID_CLIENT); | |
| String errorMessage = "Invalid Client"; |
📝 WalkthroughWalkthroughThe OAuth2 error handling in the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| if (StringUtils.isNotEmpty(appOrgId)) { | ||
| errorMessage = "Application is not available in the organization."; |
There was a problem hiding this comment.
Log Improvement Suggestion No: 2
| if (StringUtils.isNotEmpty(appOrgId)) { | |
| errorMessage = "Application is not available in the organization."; | |
| if (StringUtils.isNotEmpty(appOrgId)) { | |
| log.warn("Application not available in organization. OrgId: {}", appOrgId); | |
| errorMessage = "Application is not available in the organization."; |
There was a problem hiding this comment.
AI Agent Log Improvement Checklist
- The log-related comments and suggestions in this review were generated by an AI tool to assist with identifying potential improvements. Purpose of reviewing the code for log improvements is to improve the troubleshooting capabilities of our products.
- Please make sure to manually review and validate all suggestions before applying any changes. Not every code suggestion would make sense or add value to our purpose. Therefore, you have the freedom to decide which of the suggestions are helpful.
✅ Before merging this pull request:
- Review all AI-generated comments for accuracy and relevance.
- Complete and verify the table below. We need your feedback to measure the accuracy of these suggestions and the value they add. If you are rejecting a certain code suggestion, please mention the reason briefly in the suggestion for us to capture it.
| Comment | Accepted (Y/N) | Reason |
|---|---|---|
| #### Log Improvement Suggestion No: 1 | ||
| #### Log Improvement Suggestion No: 2 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java (1)
602-625: Add a companion non-org regression test for the default message.This test covers the org path well, but adding the no-org path assertion will lock in the
"Invalid Client"fallback and prevent regressions.Proposed test addition
+ `@Test` + public void testIssueAccessTokenWithoutOrgContextReturnsDefaultInvalidClientMessage() throws IdentityException { + + try (MockedStatic<IdentityTenantUtil> identityTenantUtil = mockStatic(IdentityTenantUtil.class); + MockedStatic<AccessTokenIssuer> accessTokenIssuer = mockStatic(AccessTokenIssuer.class)) { + identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(-1234); + identityTenantUtil.when(() -> IdentityTenantUtil.getTenantDomain(-1234)).thenReturn("carbon.super"); + AccessTokenIssuer mockAccessTokenIssuer = mock(AccessTokenIssuer.class); + accessTokenIssuer.when(AccessTokenIssuer::getInstance).thenReturn(mockAccessTokenIssuer); + when(mockAccessTokenIssuer.issue(any(OAuth2AccessTokenReqDTO.class))) + .thenThrow(new InvalidOAuthClientException("application.not.found")); + + PrivilegedCarbonContext.getThreadLocalCarbonContext().setApplicationResidentOrganizationId(null); + OAuth2AccessTokenRespDTO respDTO = oAuth2Service.issueAccessToken(new OAuth2AccessTokenReqDTO()); + assertEquals(respDTO.getErrorCode(), OAuth2ErrorCodes.INVALID_CLIENT); + assertEquals(respDTO.getErrorMsg(), "Invalid Client"); + } + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java` around lines 602 - 625, Add a companion regression test to verify the non-org/default message path: create a new test (e.g., testIssueAccessTokenWithoutOrgReturnsDefaultError) that mocks IdentityTenantUtil and AccessTokenIssuer the same way as testIssueAccessTokenWithOrgContextReturnsOrgSpecificError, have mockAccessTokenIssuer.issue(...) throw new InvalidOAuthClientException("application.not.found"), ensure PrivilegedCarbonContext.getThreadLocalCarbonContext().setApplicationResidentOrganizationId(null) (or leave unset), call oAuth2Service.issueAccessToken(new OAuth2AccessTokenReqDTO()), and assert the returned OAuth2AccessTokenRespDTO has errorCode OAuth2ErrorCodes.INVALID_CLIENT and the default errorMsg ("Invalid Client" or the current non-org message used in production) to lock in the fallback behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In
`@components/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java`:
- Around line 602-625: Add a companion regression test to verify the
non-org/default message path: create a new test (e.g.,
testIssueAccessTokenWithoutOrgReturnsDefaultError) that mocks IdentityTenantUtil
and AccessTokenIssuer the same way as
testIssueAccessTokenWithOrgContextReturnsOrgSpecificError, have
mockAccessTokenIssuer.issue(...) throw new
InvalidOAuthClientException("application.not.found"), ensure
PrivilegedCarbonContext.getThreadLocalCarbonContext().setApplicationResidentOrganizationId(null)
(or leave unset), call oAuth2Service.issueAccessToken(new
OAuth2AccessTokenReqDTO()), and assert the returned OAuth2AccessTokenRespDTO has
errorCode OAuth2ErrorCodes.INVALID_CLIENT and the default errorMsg ("Invalid
Client" or the current non-org message used in production) to lock in the
fallback behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 685f68e3-fe0b-4f74-b2d6-31bb36718258
📒 Files selected for processing (2)
components/org.wso2.carbon.identity.oauth/src/main/java/org/wso2/carbon/identity/oauth2/OAuth2Service.javacomponents/org.wso2.carbon.identity.oauth/src/test/java/org/wso2/carbon/identity/oauth2/OAuth2ServiceTest.java
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3169 +/- ##
============================================
- Coverage 57.03% 56.93% -0.11%
- Complexity 10851 10904 +53
============================================
Files 709 710 +1
Lines 61497 61937 +440
Branches 15042 15171 +129
============================================
+ Hits 35075 35261 +186
- Misses 21731 21962 +231
- Partials 4691 4714 +23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary
Fixes wso2/product-is#27163
Test plan
🤖 Generated with Claude Code