You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* fix(api): stop leaking destination errors, honour the mapped prefix, guard schedule names
Four API-layer defects recorded in docs/STATUS-AND-BACKLOG.md §6, each with a single
defensible answer, so none needed a product decision.
- `GET /jobs/{id}` and `GET /jobs/{id}/events` returned a destination's own failure text
verbatim. `S3Destination` interpolates `s3://{bucket}/{key}` plus the AWS SDK's message
and `LocalDestination` an `IOException` carrying the full server path, so both routes
handed infrastructure detail to any API caller. The runner now persists and emits only
the file name and destination type and keeps the reason in the log, matching what the
read-failure path beside it already does. Scrubbing at the runner rather than in each
destination also covers third-party `IDestination` implementations, and `UploadResult`
itself is untouched (`Abstractions` is frozen).
- `Location` was built from a hardcoded `/api`, so under `MapNeoReports("/v2")` the 202's
header was a 404 for any client that followed it. A group-level endpoint filter carries
the mapped prefix on the request and the three `Created`/`Accepted` sites build from it.
- `PUT`/`DELETE /reports/{name}/schedule` reached a name-validating override store
unguarded, so a legitimate code-first report named `sales.daily` got an
`ArgumentException` 500. Both now answer 409 naming the pattern, like the
"this host cannot do that" response already next to them. The read path guarded
already, which is what made this an oversight.
- `POST`/`PUT /sources` stored the caller's property bag unnormalized, so under
`AddInMemorySourceRegistry()` a source created over HTTP failed later with "requires a
non-empty 'connectionString' property" — the value was a `JsonElement`. Both handlers
now reuse the run endpoint's normalizer, renamed `NormalizeJsonValues` as it serves two
request shapes.
Seven tests, each verified to fail against the unfixed code. The `Location` test follows
the header instead of string-matching it, so a well-formed-but-wrong URL still fails, and
the upload assertions cover the events feed as well as the job's error.
* test(api): address CodeQL — drop the redundant cast and document TestApp.StartAsync
Copy file name to clipboardExpand all lines: docs/STATUS-AND-BACKLOG.md
+20-11Lines changed: 20 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -249,15 +249,20 @@ rather than decided:
249
249
exceptions.**~~**FIXED** (routes through `SchemaProblem` like its siblings). Original description: It catches only `ConfigurationException`, so a bad filter value surfaces the raw
250
250
`SqlException`/`PostgresException` (host, port, database) as a 500 — its siblings all route through
251
251
`SchemaProblem`. Should be a 400 (bad filter) or the scrubbed 502 the others return.
252
-
-**API: schedule/preview write paths reach a name-validating store without the guard.** The
253
-
**preview** half is **FIXED** (a name no config store can hold is now treated as not-dynamic, so the
254
-
endpoint returns its intended 400). `SetScheduleAsync`/`ClearScheduleAsync` still 500 — original
255
-
description:
252
+
-~~**API: schedule/preview write paths reach a name-validating store without the guard.**~~
253
+
**FIXED** — the preview half first (a name no config store can hold is treated as not-dynamic, so
254
+
the endpoint returns its intended 400), and now `SetScheduleAsync`/`ClearScheduleAsync` too: both
255
+
answer **409 Conflict** naming the pattern, matching the "this host cannot do that" response
256
+
already next to them, instead of an `ArgumentException` 500. Original description:
256
257
`SetScheduleAsync`, `ClearScheduleAsync` and `ReportPreviewRunner`'s config-store probe pass the
257
258
report name straight through, so a legitimate **code-first** report whose name is outside
258
259
`^[a-zA-Z][a-zA-Z0-9_-]{0,99}$` (e.g. `sales.daily`) gets a **500** from `ArgumentException`. The
259
260
read paths already guard, which shows it is an oversight.
0 commit comments