Skip to content

Commit 8aabbdc

Browse files
claude[bot]claudefelixweinberger
authored
test(e2e): expect SdkHttpError after a second 401 from onUnauthorized (#2936)
Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
1 parent 33fecfb commit 8aabbdc

2 files changed

Lines changed: 9 additions & 11 deletions

File tree

‎test/e2e/requirements.ts‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,15 +2937,9 @@ export const REQUIREMENTS: Record<string, Requirement> = {
29372937
'client-auth:authprovider:onunauthorized-retry': {
29382938
source: 'sdk',
29392939
behavior:
2940-
'When the server answers 401, the transport awaits AuthProvider.onUnauthorized() and retries the request once with the refreshed token; a second 401 (or a provider without onUnauthorized) surfaces as UnauthorizedError.',
2940+
'When the server answers 401, the transport awaits AuthProvider.onUnauthorized() and retries the request once with the refreshed token; a second 401 on that retry rejects with SdkHttpError (ClientHttpAuthentication), while a provider without onUnauthorized surfaces the 401 as UnauthorizedError.',
29412941
transports: ['streamableHttp'],
2942-
note: "This exercises the HTTP client transport's auth hook; the matrix transport arg is ignored, so it runs as a single streamableHttp-labelled cell to avoid duplicate runs.",
2943-
knownFailures: [
2944-
{
2945-
test: 'second 401 after retry surfaces as UnauthorizedError',
2946-
note: 'A second 401 after onUnauthorized() re-authentication surfaces as SdkHttpError (ClientHttpAuthentication) instead of the UnauthorizedError documented on AuthProvider.onUnauthorized().'
2947-
}
2948-
]
2942+
note: "This exercises the HTTP client transport's auth hook; the matrix transport arg is ignored, so it runs as a single streamableHttp-labelled cell to avoid duplicate runs."
29492943
},
29502944
'client-auth:authprovider:oauth-provider-adapted': {
29512945
source: 'sdk',

‎test/e2e/scenarios/client-auth.test.ts‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import {
3232
RegistrationRejectedError,
3333
resolveClientMetadata,
3434
SdkError,
35+
SdkErrorCode,
36+
SdkHttpError,
3537
SSEClientTransport,
3638
SseError,
3739
startAuthorization,
@@ -2221,7 +2223,7 @@ verifies(
22212223
const STALE = 'stale-bearer-token';
22222224
const ROTATED = 'rotated-but-still-rejected-token';
22232225

2224-
// The provider refreshes on 401 but the resource keeps rejecting: the retry's 401 must surface as UnauthorizedError.
2226+
// The provider refreshes on 401 but the resource keeps rejecting: the retry's 401 must reject with SdkHttpError (ClientHttpAuthentication).
22252227
let currentToken = STALE;
22262228
let unauthorizedCalls = 0;
22272229
const provider: AuthProvider = {
@@ -2244,7 +2246,9 @@ verifies(
22442246
const transport = new StreamableHTTPClientTransport(new URL(MCP_URL), { authProvider: provider, fetch: alwaysUnauthorizedFetch });
22452247

22462248
try {
2247-
await expect(client.connect(transport)).rejects.toThrow(UnauthorizedError);
2249+
const connectPromise = client.connect(transport);
2250+
await expect(connectPromise).rejects.toBeInstanceOf(SdkHttpError);
2251+
await expect(connectPromise).rejects.toMatchObject({ code: SdkErrorCode.ClientHttpAuthentication, status: 401 });
22482252

22492253
// onUnauthorized ran once and the transport retried exactly once before giving up.
22502254
expect(unauthorizedCalls).toBe(1);
@@ -2253,7 +2257,7 @@ verifies(
22532257
await client.close();
22542258
}
22552259
},
2256-
{ title: 'second 401 after retry surfaces as UnauthorizedError' }
2260+
{ title: 'second 401 after retry rejects with SdkHttpError' }
22572261
);
22582262

22592263
verifies('client-auth:authprovider:oauth-provider-adapted', async (_args: TestArgs) => {

0 commit comments

Comments
 (0)