refactor(api): converge the Remote failure vocabulary and client surface

Single RemoteError with a merge-extensible, domain-prefixed code map;
owners throw at the failure point; streams surface marked failures;
clients consume ctx.remote directly with isRemoteFailure as the only
discrimination point and construct no failure instances.
This commit is contained in:
imccyu
2026-08-28 22:37:36 +08:00
parent 12d7b4ed0c
commit 804b1ffbfc
252 changed files with 3182 additions and 3832 deletions
+9 -13
View File
@@ -8,7 +8,7 @@ import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-
import type {} from '@deepseek-ai/dsh-session-projection'
import type {} from '@deepseek-ai/dsh-session-projection-cache'
import { SessionQueryError, type SessionSearchCursor } from '@deepseek-ai/dsh-session-query'
import { TypertRemoteFailure } from '@deepseek-ai/dsh-typert-protocol'
import { RemoteError } from '@deepseek-ai/dsh-typert-protocol'
import { z } from 'zod'
import {
SESSION_SEARCH_RESULT_LIMIT,
@@ -226,8 +226,8 @@ export class ApiSessionList {
signal.throwIfAborted()
const provider = this.ctx.get('sessionQuery')
if (provider === undefined) {
reject(
'internal',
throw new RemoteError(
'gateway/internal',
'session search is unavailable: this deployment does not mount @deepseek-ai/dsh-session-query',
{},
)
@@ -317,9 +317,9 @@ export class ApiSessionList {
} catch (error: unknown) {
signal.throwIfAborted()
if (error instanceof SessionQueryError && error.code === 'SESSION_QUERY_ABORTED') {
reject('cancelled', 'session search was aborted', {})
throw new RemoteError('gateway/cancelled', 'session search was aborted', {})
}
reject('internal', `session search failed: ${String(error)}`, {})
throw new RemoteError('gateway/internal', `session search failed: ${String(error)}`, {})
}
}
@@ -351,25 +351,21 @@ export class ApiSessionList {
function normalizeSearchQuery(query: string): string {
const normalized = query.trim()
if (normalized.length === 0) {
reject('bad-request', 'session search query must not be empty', {})
throw new RemoteError('gateway/bad-request', 'session search query must not be empty', {})
}
if (normalized.length > SESSION_SEARCH_QUERY_MAX_CHARS) {
reject(
'bad-request',
throw new RemoteError(
'gateway/bad-request',
`session search query must contain at most ${SESSION_SEARCH_QUERY_MAX_CHARS} UTF-16 code units`,
{},
)
}
if (normalized.includes('\0')) {
reject('bad-request', 'session search query must not contain NUL', {})
throw new RemoteError('gateway/bad-request', 'session search query must not contain NUL', {})
}
return normalized
}
function reject(code: string, message: string, details: object): never {
throw new TypertRemoteFailure({ code, message, details })
}
function updatedAt(header: SessionHeader, metadata: SessionListMetadata | undefined): number {
return Math.max(header.createdAt, metadata?.lastPromptAt ?? 0)
}