Repository navigation
fix(service-datasource, rest): the datasource Sync doors and federation twins answer an unknown name 404 RESOURCE_NOT_FOUND - #27693
Conversation
…e name 404 RESOURCE_NOT_FOUND The federation guard folded a name with no datasource definition into the "not a federation source" 400. It now throws the package's one datasourceNotFoundError (the two private copies are merged into one helper in datasource-admin-service.ts, not exported from the package index), and the rest federation twins relay that 404 envelope as the admin routes do. A definition that is not a federation source keeps its 400. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6bhgXTXpQTz45k8v4WACt
📓 Docs Drift CheckThis PR changes 2 package(s): 11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 6 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 21 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin e510e960736a78761d5d426faad5418dec7b5f86 && git checkout e510e960736a78761d5d426faad5418dec7b5f86
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin bfdaba4322e1258a7657aa622af021e31ab071aa 2d19915cdc0c3038e47676735a6ab4cd8f659e96 && git checkout -B drift-repro bfdaba4322e1258a7657aa622af021e31ab071aa && git merge --no-ff 2d19915cdc0c3038e47676735a6ab4cd8f659e96
node scripts/docs-audit/affected-docs.mjs --json bfdaba4322e1258a7657aa622af021e31ab071aa
|
|
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F 维护者速读(席位终稿)
席位意见: ACCEPT。拒绝本来就有,只是换成和读门一致的 404;一个包里只剩一个「数据源不存在」的写法。 席位核对ACCEPT · head
|
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
Requested by Sales · project thread
Fixes #27618
Clause-②: no
Metadata-protocol: none
Skills-docs: none — the kind is
noneand there is no narrowing arm; noskills/**orcontent/docspage states what these doors answer for an unknown datasource name (git grepforremote-tables,object-draft,refresh-catalog,has no datasource definitionoutside the release notes: no such sentence).Claim: 6504788091 (seat
domain:server#2, branchclaude/project-thread-bvrf7w, the card thread's harness-pinned branch). Triage direction: 6500612695. Ruling: none.维护者速读
/external/下的四个联邦入口(列表、草稿、导入、刷新目录),对一个根本不存在的数据源名,现在统一回404 RESOURCE_NOT_FOUND,措辞与GET /datasources/NAME完全一致;包内「数据源不存在」的报错收成一个共用函数。400,还附一段「请把数据源声明为 external」的说教,管理工具、脚本和 AI 调用方会误以为是请求写错了,而其它按名入口早已回 404。packages/services/service-datasource/src/external-datasource-service.ts(assertFederationSource新增的「无定义」分支)、packages/rest/src/external-datasource-routes.ts(answerThrown的 404 透传)、packages/services/service-datasource/src/datasource-admin-service.ts(唯一的datasourceNotFoundError)。pnpm --filter @objectstack/rest exec vitest run src/external-datasource-unknown-name.test.ts,预期 12 个用例全绿(4 个入口回 404,8 个对照仍回 400)。What changes
ExternalDatasourceService.assertFederationSource(the guard every federation door runs first) now splits the two cases it folded together: a name with no datasource definition throws the 404RESOURCE_NOT_FOUNDenvelope (Datasource "NAME" does not exist.), and a definition that is not a federation source keeps its400with the door's code (EXTERNAL_DATASOURCE_ERROR, orEXTERNAL_IMPORT_ERRORfor the import). The primary datasource is still refused first, by name, with its own400.notAFederationSourceErrorno longer takes an absent definition, so its dead "has no datasource definition" arm is gone.datasourceNotFoundErrorcopies (admin service, external service) are merged into one indatasource-admin-service.ts, exported from that module for its siblings only. ⛔ It is not added to the package index (src/index.tsuses named exports only and is unchanged), so the published surface does not move.GET /datasources/NAMEinadmin-routes.tsnow takes its 404 words from the same helper, so every by-name door spells the answer once.service-datasource's admin routes already relayed that envelope as 404 (badRequest), soGET …/remote-tablesandPOST …/object-draftneeded no route change, only the guard.packages/rest's federation family answered every non-fault throw400.answerThrownnow relays the 404 /RESOURCE_NOT_FOUNDenvelope as such (both fields required, as inbadRequest), soGET …/external/tables,POST …/external/tables/REMOTE/draft,POST …/external/tables/REMOTE/importandPOST …/external/refresh-cataloganswer an unknown name asGET /datasources/NAMEdoes. Every other throw keeps this family's400and code.Tests
service-datasource/src/__tests__/federation-doors-unknown-name.test.ts, over the real composition (realObjectQL, connection service, admin service,ExternalDatasourceServicePluginwiring, admin routes on Hono, an entitled caller):GET /datasources/no_such_ds/remote-tablesandPOST /datasources/no_such_ds/object-draftanswer status, code and message equal toGET /datasources/no_such_ds(404RESOURCE_NOT_FOUND); controls: a managed datasource and the primary datasource still answer400 EXTERNAL_DATASOURCE_ERRORwith their reasons.rest/src/external-datasource-unknown-name.test.ts, the real service under the real routes on Hono: the four/external/twins answer404 RESOURCE_NOT_FOUND,Datasource "no_such_ds" does not exist.(GET's words); controls: managed and primary datasources still answer400with each door's own code.managed-datasource-sync-refusal.test.ts(theghostcase now expects the 404) andexternal-metadata-read-at-use.test.ts(the no-metadata-service case now expects the 404 envelope from all four service methods).service-datasource404 pins and the 4 newrest404 pins were red (400 EXTERNAL_DATASOURCE_ERROR/EXTERNAL_IMPORT_ERROR, "has no datasource definition …"), the controls green.Acceptance notes
scripts/ablation-replace.mjs, fix committed first, restore blob == HEAD andgit diff HEADempty). Both suites read source (service-datasourcetests importsrc/directly;rest'svitest.config.tsaliases@objectstack/service-datasourceto itssrc/index.ts), so nodist/rebuild is in either leg.if (!ds) throw datasourceNotFoundError(datasource);inassertFederationSource:service-datasource2 failed / 4 passed,rest4 failed / 8 passed (every 404 pin red, every 400 control green). Restored blob922e07c2df3d== HEAD.rest'sanswerThrown:rest4 failed / 8 passed, received400 EXTERNAL_DATASOURCE_ERROR/400 EXTERNAL_IMPORT_ERROR. Restored blob1629a50c6b7e== HEAD.POST /datasources/NAME/testalready makes since fix(service-datasource)!: POST /datasources/:name/test answers an unknown name 404 RESOURCE_NOT_FOUND #27574 (it resolves through the samegetDatasourceread), so the by-name doors stay one answer; noted, not a change of direction.POST /datasources/NAME/external/validatedoes not run the federation guard (it lists the federated objects bound to NAME), so an unknown name answers200with an empty report. That is code reading only (no door measured), outside this card's doors.claude/project-thread-bvrf7w, not theclaude/issue-N-slugconvention; the claim above is its identity record.Verification
All on head
2d19915c(the fix commit88e7fb01merged withorigin/mainat50d05cb1).Package suites and typecheck
pnpm --filter @objectstack/service-datasource test && … typecheckunderos-verify-lock.sh:VERDICT command-exit 0, Test Files 61 passed (61), Tests 1010 passed (1010).pnpm --filter @objectstack/rest test && … typecheckunderos-verify-lock.sh:VERDICT command-exit 0, Test Files 340 passed (340), Tests 6674 passed, 326 skipped (7000).eslint --no-inline-configon the 8 changed source and test files: exit 0.pnpm lint(repo-wideeslint . --no-inline-config) on2d19915c: exit 0, no findings.Derived gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 62 families derived at2d19915c. All 62 run, eachexit 0(check:dual-build-cjs-loadsfirst answered exit 3, a prerequisite with 48 dists missing; after a fullturbo run buildit answered exit 0: 112 require entry points across 69 packages load).--ranreconcile:62 derived famil(ies) accounted for — 62 run, 0 NOT-MEASURED.merge-treepair was owed.Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01L6bhgXTXpQTz45k8v4WACt