diff --git a/src/lib/xrpc-error.ts b/src/lib/xrpc-error.ts index 5ee89ca0fc..25f9a1277e 100644 --- a/src/lib/xrpc-error.ts +++ b/src/lib/xrpc-error.ts @@ -7,6 +7,18 @@ import { XrpcResponseError, } from '@atproto/lex' +/** + * Same nsid means `e` was thrown for this method schema, so `e` can be + * treated as an `XrpcResponseError` - which is what lets the SDK's + * `matchesSchemaErrors()` narrow `e.error` to M's declared errors. + */ +function isThrownFor( + e: XrpcResponseError, + schema: M, +): e is XrpcResponseError { + return e.method.nsid === schema.nsid +} + /** * The lexicon error code carried by `e`, narrowed to the errors DECLARED by * `method`, or `undefined` when `e` is not such an error. @@ -39,12 +51,9 @@ export function matchXrpcError( if (!(e instanceof XrpcResponseError)) { return undefined } - const schema: Procedure | Query = getMain(method) - const thrownFor: Procedure | Query = e.method - if (thrownFor.nsid !== schema.nsid) { - return undefined + const schema = getMain(method) + if (isThrownFor(e, schema) && e.matchesSchemaErrors()) { + return e.error } - return schema.errors?.includes(e.error) - ? (e.error as InferMethodError) - : undefined + return undefined }