Skip to content

finding(app-shell): PackageFormDialog holds a fourth copy of the envelope ladder and still drops error.userMessage and error.code #7979

Description

@os-sam

Observation

Found while implementing objectui#7959 (extracting the ADR-0112 failure-envelope read that
fetchPackages, apiJson and duplicatePackage each held their own copy of). That card's
declared file surface is views/studio-design/packages-io.ts and PackagesPage.tsx's
apiJson, so this one was deliberately left alone rather than fixed as a rider.

packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx holds a fourth
instance of the same ladder, character for character the one apiJson had before objectui#7959:

// PackageFormDialog.tsx:62
payload?.error?.message || payload?.error || payload?.message || `Request failed (${res.status})`;

It reads the diagnostic error.message and stops. So it drops both of the things the other
three readers now render:

  • error.userMessage — the producer's #9934 marked channel. Presence of the field IS the
    producer's marking, and the envelope writer's rule is that "a consumer that sees the field
    renders it verbatim". In the 5xx band the door substitutes the generic Internal server error into message while the mark rides through untouched, so on a marked 500/503 this
    dialog shows the author the generic sentence and discards the specific one written for them.
  • error.code, which never reaches the author at all.

Why it is live, not theoretical

This dialog POSTs and PUTs /api/v1/packages — the same route family objectui#7959 measured.
Both doors that serve it spread the marked channel onto the wire: sendThrownError
(@objectstack/rest package-routes.ts) and its dispatcher twin errorFromThrown
(@objectstack/runtime http-dispatcher.ts), which the REST door's own note calls "byte for
byte the dispatcher twin's expression … which serves this same path and has emitted the
channel since #9934". The framework pins the pair wire-side in package-door-user-message.test.ts.

Create/edit are exactly where an author meets a refusal that names what to fix — a namespace
rule, a capability to grant, a version already published.

The fix is now mechanical

objectui#7959 extracted the rule to packages/app-shell/src/utils/apiErrorEnvelope.ts
(readEnvelopeFailureText), pinned in apiErrorEnvelope.test.ts. This site becomes:

const msg =
  readEnvelopeFailureText(payload) || payload?.error || payload?.message || `Request failed (${res.status})`;

— the two rungs below stay, because a bare-string error and a top-level message are older
runtimes' shapes and not this envelope. Wants its own pin over the four combinations
(message only / userMessage only / both / neither) plus the code interaction, matching
PackagesPage.envelopeUserMessage.test.tsx.

Re-check

sed -n '55,70p' packages/app-shell/src/views/metadata-admin/PackageFormDialog.tsx
grep -rn "readEnvelopeFailureText" packages/app-shell/src/

Related, not duplicates: objectui#7959 (the three readers this one was left out of),
objectui#7938 / PR objectui#7960 (fetchFullPackage), objectui#7368 (the report channel),
objectui#4634 (the same family: a reader discarding the kernel's sentence).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpackage: app-shellpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions