v2 backwards compat: SdkError status code#2049
Open
KKonstantinov wants to merge 4 commits into
Open
Conversation
🦋 Changeset detectedLatest commit: 4932aae The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/server
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add
SdkHttpErrorsubclass for typed HTTP transport error handlingMotivation and Context
SdkErrorcarries HTTP failure details (status code, status text) in itsdata?: unknownfield. Consumers who need to inspect the HTTP status — for example, to handle 401 or 403 responses — must resort to unsafe casting:This also affects v1 migration: the old
StreamableHTTPErrorhad a typedcode: numberfor HTTP status, but the v2 replacementSdkErrorusescode: SdkErrorCode(an enum, not an HTTP status). There is no typed way to access the HTTP status in v2.How Has This Been Tested?
pnpm build:all— all packages build successfullypnpm typecheck:all— no type errorspnpm lint:all— no lint or formatting issuespnpm test:all— all existing tests pass (core: 552, client: 364)streamableHttp.test.ts,tokenProvider.test.ts, andsse.test.tsto verifyinstanceof SdkHttpErrorand the.statusaccessorBreaking Changes
None.
SdkHttpError extends SdkError, so existingcatchclauses andinstanceof SdkErrorchecks continue to work. This is a purely additive change — consumers can opt in to more precise error handling viainstanceof SdkHttpErrorwithout changing existing code.Types of changes
Checklist
Alternatives Considered
A. Generic
SdkError<C>with data type map — ASdkErrorDataMapmapping eachSdkErrorCodeto its data shape, withSdkError<C>.dataconditionally typed. Rejected because TypeScript doesn't narrow class generics via property checks — consumers can't writeif (error.code === SdkErrorCode.X)and get narroweddata. Requires a helper function, which is non-standard for error handling.B. Broaden
SdkError.datato{ status?: number; statusText?: string; ... }— Rejected because it's misleading: suggests everySdkErrormight have HTTP status fields, evenNotConnectedorRequestTimeoutwhich have no HTTP context.C. Add
httpStatusaccessor onSdkErrorbase class —get httpStatus(): number | undefinedthat extracts fromdata. Rejected because the base class shouldn't know about HTTP semantics, and consumers can't distinguish HTTP errors structurally at the type level.D. HTTP error subclass (chosen) —
SdkHttpError extends SdkErrorwith typeddata. Standardinstanceofpattern, backward compatible, follows established SDK patterns (AWS SDK v3ServiceException, StripeStripeAPIError, gRPCServiceError). One new class, no generics, no type maps.Additional context
Files changed:
packages/core/src/errors/sdkErrors.ts— AddedSdkHttpErrorDatainterface andSdkHttpErrorclass withstatus/statusTextgetterspackages/core/src/exports/public/index.ts— ExportedSdkHttpErrorandSdkHttpErrorDatapackages/client/src/client/streamableHttp.ts— Changed 5 throw sites fromSdkErrortoSdkHttpErrorfor HTTP failurespackages/client/src/client/sse.ts— Changed 1 throw site (401 after retry) fromSdkErrortoSdkHttpErrorpackages/client/test/client/streamableHttp.test.ts— Updated assertions to useSdkHttpErrorpackages/client/test/client/tokenProvider.test.ts— Updated assertions to useSdkHttpErrorpackages/client/test/client/sse.test.ts— Updated assertions to useSdkHttpErrorDesign decision: The
ClientHttpUnexpectedContenterror instreamableHttp.tswas intentionally left asSdkError— it fires on a 200 OK response with an unexpected content type, so it doesn't carry an HTTP error status and doesn't fit theSdkHttpErrorDatashape.Consumer usage after this change: