Repository navigation
public-api-http: make Native error rendering usable outside space-api - #1364
Merged
Merged
Conversation
This was referenced Nov 3, 2026
nikhilbirmiwal-pplx
approved these changes
Nov 3, 2026
nikhilbirmiwal-pplx
left a comment
Member
There was a problem hiding this comment.
Diffed the new public-api-http error.rs/request_id.rs against the old space-api error.rs/request_context.rs: verbatim apart from visibility, the retry_after_header_value/LOCK_CONTENTION_RETRY_AFTER relocation (same value/logic), and the same request_id_from_headers (common_svc re-exports it). database_error matches the old Fromsqlx::Error exactly, the call-site rewrites are mechanical, and the file-error From impls moved unchanged; no behaviour change found.
NancyKwongPerplexity
force-pushed
the
native-files-shared-handling
branch
from
November 3, 2026 19:39
f99ebdc to
03f4885
Compare
NancyKwongPerplexity
force-pushed
the
native-error-rendering-shared
branch
from
November 3, 2026 19:39
0c7cba6 to
1be4b2a
Compare
NancyKwongPerplexity
force-pushed
the
native-files-shared-handling
branch
from
November 3, 2026 20:09
03f4885 to
194d52c
Compare
Move PublicApiError, its error contract, its rendering into the Native envelope, the request-id middleware and the normalization of framework rejections and unhandled error statuses out of space-api into a new pplx-space-public-api-http crate in crates/l40_api, so another server answering Native routes renders the same envelopes, statuses and headers. space-api keeps the conversions from its own errors. The Rust orphan rule does not allow it to keep `From<sqlx::Error> for PublicApiError` once the type lives elsewhere, so its 32 `?` and `from` sites now call `database_error`, which classifies and logs exactly as the impl did. The file errors' conversions move into pplx-space-native-files. The error and request-id tests that need nothing from space-api move with the code; the database and session ones stay. No behaviour change.
NancyKwongPerplexity
force-pushed
the
native-error-rendering-shared
branch
from
November 3, 2026 20:43
1be4b2a to
41953a9
Compare
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.
Summary
Moves the Native error contract out of space-api into a new crate,
pplx-space-public-api-http(crates/l40_api/public/api/http), so another server answering Native routes renders the same envelopes, statuses and headers. The crate contains:PublicApiError, witherror_contract, its constructors, andIntoResponseinto the Native envelope. That coversRetry-After, thepublic_api.responsemetric and the span classification.x-request-id, or issuereq_<uuid>. The current id is exposed ascurrent_request_idandscope_request_id.normalize_public_error_response: framework rejections (405, 413, 415, 422) and unhandled error statuses become an envelope that keeps its status.public_route_not_found,with_retry_after_hint,retry_after_header_valueandLOCK_CONTENTION_RETRY_AFTER.controllers::substrate's constant now names the crate's, and its rationale stays where it is.space-api re-exports these from
routes::public::errorand keeps the conversions from its own store errors. The Rust orphan rule does not allowimpl From<sqlx::Error> for PublicApiErroroutside the crate that definesPublicApiError, so the 32 call sites that relied on it now calldatabase_error. That function classifies a lock race as the retryable 503 and logs everything else, exactly as the impl did. The comments that named the impl now name the function. The file errors' conversions intoPublicApiErrormove intopplx-space-native-files.classification_for_testbecomes the publicclassification(), because a test-only accessor cannot cross a crate boundary.No behaviour change.
Validation
At this head (
1be4b2ad), onmainat0271415a:git range-diffdiffers only in context:main(api: page and filter the admin sandbox list, count spaced versions, and share one sandbox ID parser #1321) changed the line above onedatabase_errorcall inroutes/admin/sandboxes.rs.cargo fmt --all -- --check,scripts/generate-env-contract.sh --check,scripts/check-rust-error-policy.shandscripts/source_guards/env_test_hook_boundary.pypass.cargo clippy --locked --all-targets --all-features -p pplx-space-native-files -p pplx-space-api -p pplx-space-public-api-http -- -D warningspasses.cargo check --workspace --all-targets --lockedpasses.cargo archagainstmain's baseline, renames andARCHITECTURE.toml: 0 required findings and 112 advisory, the same findings asmain.cargo nextest run --config 'profile.test.package.pplx-space-api.opt-level=0' --all-features --all-targets, one package at a time, with Postgres and Redis from the nextest setup scripts andSPACE_CI_REQUIRE_TEST_DEPS=1:pplx-space-api2184 passed, 1 skipped;pplx-space-native-files1 passed;pplx-space-public-api-http9 passed.cargo clippy -p <crate> --all-targets --all-features -- -D warnings, separate target directory), as the isolated-crates check does.The error and request-id tests that need nothing from space-api move with the code. The lock-contention test for
sqlx, operation-store and session-store errors, and the ended-session test, stay in space-api. They now read status and classification throughclassification()andretryablefrom the rendered envelope.Severity and risk
Severity: does not apply (refactor).
Risk: a missed
database_errorsite would fail to compile rather than change behaviour, because no conversion fromsqlx::Errorexists any more. The rendering code moves verbatim. To roll back, revert this PR.Stack
This is PR 3 of 5 and depends on #1363 (
native-files-shared-handling). Merge in order:native-files-shared-request)native-files-shared-handling)native-file-access-rpcs)data-plane-native-file-access-authz)AI assistance: Claude Code drafted the code, tests, and this description; the author reviewed them.