Skip to content

API, Core: Add exceptions for OAuth2 token endpoint errors#16507

Open
oguzhanunlu wants to merge 2 commits into
apache:mainfrom
oguzhanunlu:oauth2-typed-exceptions
Open

API, Core: Add exceptions for OAuth2 token endpoint errors#16507
oguzhanunlu wants to merge 2 commits into
apache:mainfrom
oguzhanunlu:oauth2-typed-exceptions

Conversation

@oguzhanunlu

@oguzhanunlu oguzhanunlu commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary
Follow-up to #15746 / #16059 . Same unreliable triage pattern, at the OAuth2 token endpoint instead of /v1/config.

Background
OAuth2 token endpoint failures (RFC 6749 §5.2) currently surface as generic BadRequestException / NotAuthorizedException, with the error type stringified into the exception message. Consumers that triage on the error type must regex-parse the message to recover it.

This PR introduces exceptions that carry the OAuth2 error type as a field accessible via a marker interface:

OAuth2Error                  (marker, String errorType())
OAuth2BadRequestException    extends BadRequestException implements OAuth2Error    (400)
OAuth2NotAuthorizedException extends NotAuthorizedException implements OAuth2Error    (401)

OAuthErrorHandler.accept now throws these for all six RFC 6749 §5.2 codes (invalid_request, invalid_client, invalid_grant, unauthorized_client, unsupported_grant_type, invalid_scope).

Design
Two classes (per HTTP status), not six (per error type). Different reasons within an HTTP status class are unified under one exception per status, consistent with how BadRequestException covers all 400s currently.

Backward compatible: getMessage() output is byte-identical and existing catch blocks on BadRequestException / NotAuthorizedException continue to fire.

Adds six unit tests that pin which exception is thrown for each OAuth2 error type.

devlist: https://lists.apache.org/thread/h3ryzblzs1hv8g5ldrxppvmy5dwrhvx8

OAuth2 token endpoint failures (RFC 6749 §5.2) currently surface as
generic BadRequestException / NotAuthorizedException, with the error
type stringified into the exception message. Consumers that triage on
the error type must regex-parse the message to recover it unreliably.

Introduce exceptions that carry the OAuth2 error type as a field
accessible via a marker interface:

  - OAuth2Error                  (marker, String errorType())
  - OAuth2BadRequestException    extends BadRequestException
                                 implements OAuth2Error    (400)
  - OAuth2NotAuthorizedException extends NotAuthorizedException
                                 implements OAuth2Error    (401)

OAuthErrorHandler.accept now throws these for all six RFC 6749 §5.2
codes (invalid_request, invalid_client, invalid_grant,
unauthorized_client, unsupported_grant_type, invalid_scope).

Design:
Two classes (per HTTP status), not six (per error type). Different
reasons within an HTTP status class are unified under one exception per
status, consistent with how BadRequestException covers all 400s
currently.

Backward compatible: getMessage() output is byte-identical and
existing catch blocks on BadRequestException / NotAuthorizedException
continue to fire.

Adds six unit tests that pin which exception is thrown for each OAuth2
error type.
@oguzhanunlu oguzhanunlu force-pushed the oauth2-typed-exceptions branch from 46bb502 to 6b075a2 Compare June 12, 2026 14:55
@oguzhanunlu

Copy link
Copy Markdown
Contributor Author

Just a friendly ping for review when you have time @kevinjqliu . Happy to address any feedback. Thanks in advance!

@adutra adutra 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.

Thanks @oguzhanunlu, this seems like a nice enhancement.

}

@FormatMethod
public OAuth2BadRequestException(

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.

This constructor seems unused / untested.

}

@FormatMethod
public OAuth2NotAuthorizedException(

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.

Same for this constructor.

@oguzhanunlu

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback @adutra ! I dropped both in the new commit.

@oguzhanunlu oguzhanunlu requested a review from adutra July 3, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants