user visible error rather than crash on projections --vs <date> with imported data
This commit is contained in:
parent
8fe9257c60
commit
f10508932e
2 changed files with 17 additions and 23 deletions
22
TODO.md
22
TODO.md
|
|
@ -631,28 +631,6 @@ malformed flag" behavior (above) means
|
|||
`zfin interactive --default-keys --bogus-flag` is accepted; the
|
||||
bogus flag is silently dropped. Same fix as above.
|
||||
|
||||
### `projections --vs <date>` crashes with `FileNotFound` when as-of resolves to imported source — priority MEDIUM
|
||||
|
||||
Repro: `zfin projections --vs 2025-01-01` (any date that resolves
|
||||
to imported_values rather than a real snapshot) →
|
||||
`error: FileNotFound` panic with stack trace.
|
||||
|
||||
Root cause: `loadAsOfContext` in `src/commands/projections.zig:760-762`
|
||||
calls `history.loadSnapshotAt` unconditionally, but the resolution
|
||||
returned by `resolveAsOfSnapshot` can have `source == .imported`
|
||||
when the only available data point at that date is from
|
||||
imported_values, not a real snapshot file. `loadSnapshotAt` then
|
||||
fails to open a file that doesn't exist.
|
||||
|
||||
`runBands` at line 369 has the same setup but correctly branches:
|
||||
`if (resolution.?.source == .snapshot) { loadSnapshotAt(...) } else { loadProjectionContextFromImported(...) }`.
|
||||
`loadAsOfContext` should mirror that branching.
|
||||
|
||||
Pre-existing bug from before the framework refactor. Surfaced
|
||||
during the sanity check because the new dispatcher correctly
|
||||
identifies `FileNotFound` as not a user-level error and propagates
|
||||
with stack trace. Pre-fix the same crash happened, just hidden.
|
||||
|
||||
### `etf <SYMBOL>` warns `failed to serialize ETF profile: WriteFailed` — priority LOW
|
||||
|
||||
Every `zfin etf VTI` invocation prints
|
||||
|
|
|
|||
|
|
@ -742,9 +742,18 @@ fn extractKeyMetrics(ctx: view.ProjectionContext) KeyMetrics {
|
|||
|
||||
/// Build a `ProjectionContext` against a historical snapshot date.
|
||||
///
|
||||
/// Caller owns `snap_bundle_out.*` on success — it must outlive the
|
||||
/// Caller owns `snap_bundle_out.*` on success - it must outlive the
|
||||
/// returned context because allocations borrow symbol strings from
|
||||
/// the snapshot's backing buffer.
|
||||
///
|
||||
/// Imported-only resolutions (where the requested date predates any
|
||||
/// real snapshot but is covered by `imported_values.srf`) are NOT
|
||||
/// supported here: the imported-only path needs live-portfolio
|
||||
/// composition plumbed through additional outparams that this helper
|
||||
/// doesn't expose. Callers that hit this case get `error.NoSnapshot`
|
||||
/// after a clear stderr message, mirroring the user-visible behavior
|
||||
/// of "no snapshot at that date." See the `--vs` follow-up TODO for
|
||||
/// the parity work that would make this branch fully supported.
|
||||
fn loadAsOfContext(
|
||||
io: std.Io,
|
||||
allocator: std.mem.Allocator,
|
||||
|
|
@ -758,6 +767,13 @@ fn loadAsOfContext(
|
|||
snap_bundle_out: *history.LoadedSnapshot,
|
||||
) !view.ProjectionContext {
|
||||
resolution_out.* = resolveAsOfSnapshot(io, va, file_path, requested_date) catch |err| return err;
|
||||
if (resolution_out.source != .snapshot) {
|
||||
// Imported-only resolution: no snapshot file exists at the
|
||||
// resolved date, so `loadSnapshotAt` would crash with
|
||||
// FileNotFound. Bail with a clear message instead.
|
||||
try cli.stderrPrint(io, "Error: --vs does not yet support back-dating to imported-only periods (no snapshot at that date).\n");
|
||||
return error.NoSnapshot;
|
||||
}
|
||||
const hist_dir = try history.deriveHistoryDir(va, file_path);
|
||||
snap_bundle_out.* = try history.loadSnapshotAt(io, allocator, hist_dir, resolution_out.actual);
|
||||
return try view.loadProjectionContextAsOf(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue