Repository navigation
Commit a9c5ea0
fix(fields): a file URL whose last segment holds a bare
Fixes #10614
Clause-②: no
## What changed
`nameFromUrl` in `packages/fields/src/widgets/file-value.ts` names a
file value that carries no name after its URL's last path segment,
decoded with `decodeURIComponent`. A segment that is not a valid
percent-encoding made the decode throw `URIError: URI malformed`, and
the throw left `readFileValue` during render. The decode is now guarded
once, in that helper. On `URIError` the name is the raw segment; any
other error is rethrown. No caller changed, and no caller has its own
try/catch (triage ruling on the card, comment `5833345168`). A valid
escape decodes exactly as before.
Files: `packages/fields/src/widgets/file-value.ts` (the guard and its
doc comment), `packages/fields/src/widgets/file-value.test.ts` (helper
pins),
`packages/fields/src/widgets/file-value.bare-percent-10614.test.tsx`
(rendered-face pins, new), `.changeset/10614-file-name-bare-percent.md`
(patch, `@object-ui/fields`).
## Reach, measured first at the base `eca2760`
A scratch harness (not committed) mounted every face that reaches the
helper. Values: `https://cdn.example.com/100%.png` (string) and `{ url:
'https://cdn.example.com/a%zz.pdf' }` (object).
| Face | At the base | After the fix |
|---|---|---|
| `file` cell (`FileCellRenderer`), string and array | throws `URIError:
URI malformed` | link named `100%.png` / `a%zz.pdf` |
| `image` cell (`ImageCellRenderer`), string and object | throws
`URIError: URI malformed` | renders |
| `signature` cell (via `getCellRenderer`) | throws `URIError: URI
malformed` | renders |
| `FileField` edit and readonly | throws `URIError: URI malformed` |
renders, name shown |
| `FileCell` | throws `URIError: URI malformed` | renders, name shown |
| `ImageField` edit and readonly | throws `URIError: URI malformed` |
renders |
| `object-grid` through `SchemaRenderer`, one bad row plus one valid row
| the `data-table` node's error boundary replaces the WHOLE table with
its panel `Component "data-table" failed to render` / `URI malformed` /
`Retry`. Neither row is visible. | both rows visible, no alert |
| `object-gallery` through `SchemaRenderer`, one bad cover plus one
valid | the gallery's boundary replaces the whole gallery with
`Component "object-gallery" failed to render` / `URI malformed` /
`Retry` | both cards visible, no alert |
| control: `file` cell with `report%20q3.pdf` | `report q3.pdf` |
`report q3.pdf` |
So at the base, no face contained the throw. Under `SchemaRenderer`, the
nearest error boundary caught it, and one such value hid the whole table
or gallery, valid rows included. The measurement did not produce a blank
page, because `SchemaRenderer` wraps every node in a boundary. The
console's list route reaches the grid through `ListView`, which renders
it through `SchemaRenderer`. `ObjectGallery`'s cover (`resolveCoverUrl`
calls `readFileValues`) is a caller the card did not list. `git grep`
found it, and it was measured above.
## Pins, and the ablation
- `file-value.test.ts`, the describe block whose name ends `names the
file by its raw segment (objectui#10614)`. It pins both reported values
(no throw, name is the raw segment), the two together through
`readFileValues`, and THE CONTROL: `report%20q3.pdf` still decodes to
`report q3.pdf`, both as a string and as `{ url }`.
- `file-value.bare-percent-10614.test.tsx` renders the `file` cell
through `getCellRenderer('file')`. It checks both values as links named
by the raw segment with the right `href`, a single non-array value, and
the control decoding beside a bare-`%` value in the same cell.
- Ablation, run on the committed fix `551e8ed` with
`ablation-replace.mjs` (wrap mode, anchor `if (err instanceof URIError)
return seg;` deleted, so the throw escapes again as it did at the base).
It printed `anchor x1 -> x0` and blob `a2c261c8e7d4 -> e873660a8615`.
The two pin files then read `Tests 6 failed | 39 passed (45)`, `command
exited 1`, and every failure is `URIError: URI malformed`. The helper
control stays green in that run, as a control should. Restore: `blob ==
HEAD (a2c261c) and git diff HEAD is empty`. Direction observed:
red, as expected.
## Gates, at head `1980ada` (after merging `origin/main` `f99f9cd`)
- `pnpm exec vitest run packages/fields/`: exit 0, `Test Files 209
passed | 1 skipped (210)`, `Tests 3399 passed | 7 skipped (3406)`
- `pnpm turbo run type-check --filter @object-ui/fields
--concurrency=2`: exit 0, `Tasks: 12 successful, 12 total`, and
`@object-ui/fields:type-check: cache miss, executing`, so it ran rather
than replaying a cache. `tsc -p tsconfig.test.json --listFiles` lists
both pin files, so the test program covers them.
- `pnpm exec eslint` on the three changed source and test files: exit 0,
no problems
- `pnpm check:control-bytes`, `check:test-path-roots`,
`check:vi-mock-specifiers`, `check:vi-mock-inherit`,
`check:vi-mock-override-shape`, `check:new-line-citations` (0 new),
`check:changeset-claims`, `check:pending-changeset-literals`,
`check:unreferenced-sources`: exit 0 each
- `node scripts/check-changeset-presence.mjs`,
`check-changeset-no-major.mjs`, `check-changeset-overwrite.mjs`,
`check-lint-coverage.mjs`: exit 0 each
- The repo-wide `pnpm lint` and the full test shards belong to CI.
## Acceptance notes
- The boundary granularity is an observation, not a filed card.
`SchemaErrorBoundary` sits at the schema node, so any throw from one
cell renderer blanks the whole `data-table` node, not the cell. This
card removes the throw. It does not change where boundaries sit.
- The fix names a file by its raw segment. It does not validate the URL.
The `href` is the value's own URL, unchanged.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01KUxVUa7e39aNjhkKi1gsoy)_
---------
Co-authored-by: Claude <noreply@anthropic.com>% renders, named by its raw segment (objectui#10614) (#10653)1 parent 3d17a97 commit a9c5ea0
4 files changed
Lines changed: 148 additions & 1 deletion
File tree
- .changeset
- packages/fields/src/widgets
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
Lines changed: 73 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
148 | 183 | | |
149 | 184 | | |
150 | 185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
117 | 117 | | |
118 | 118 | | |
119 | 119 | | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
120 | 130 | | |
121 | 131 | | |
122 | 132 | | |
123 | 133 | | |
124 | 134 | | |
125 | | - | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
126 | 142 | | |
127 | 143 | | |
128 | 144 | | |
| |||
0 commit comments