Relay annot creation failures with err-dict resps

Change annot-ctl APIs to return `None` on failure instead of invalid
`aid`s. Server now sends `{'error': msg}` dict on failures, client
match-blocks handle gracefully.

Also,
- update return types: `.add_rect()`, `.add_arrow()`, `.add_text()`
  now return `int|None`
- match on `{'error': str(msg)}` in client IPC receive blocks
- send error dicts from server on timestamp lookup failures
- add failure handling in `markup_gaps()` to skip bad rects

(this commit msg was generated in some part by [`claude-code`][claude-code-gh])
[claude-code-gh]: https://github.com/anthropics/claude-code
multiaddrs
Gud Boi 2026-01-28 14:43:52 -05:00
parent 51d109f7e7
commit 858cfce958
2 changed files with 41 additions and 15 deletions

View File

@ -220,7 +220,16 @@ async def markup_gaps(
)
# add up/down rects
aid: int = await actl.add_rect(**rect_kwargs)
aid: int|None = await actl.add_rect(**rect_kwargs)
if aid is None:
log.error(
f'Failed to add rect for,\n'
f'{rect_kwargs!r}\n'
f'\n'
f'Skipping to next gap!\n'
)
continue
assert aid
aids[aid] = rect_kwargs
direction: str = (

View File

@ -155,12 +155,14 @@ async def serve_rc_annots(
1: ds.chart,
}[timeframe]
except KeyError:
log.warning(
msg: str = (
f'No chart for timeframe={timeframe}s, '
f'skipping rect annotation'
)
await annot_req_stream.send(-1)
log.exeception(msg)
await annot_req_stream.send({'error': msg})
continue
cv: ChartView = chart.cv
# NEW: if timestamps provided, lookup current indices
@ -179,21 +181,23 @@ async def serve_rc_annots(
# lookup start index
start_matches = arr[arr['time'] == start_time]
if len(start_matches) == 0:
log.error(
f'No shm entry for start_time='
f'{start_time}, skipping rect'
msg: str = (
f'No shm entry for start_time={start_time}, '
f'skipping rect'
)
await annot_req_stream.send(-1)
log.error(msg)
await annot_req_stream.send({'error': msg})
continue
# lookup end index
end_matches = arr[arr['time'] == end_time]
if len(end_matches) == 0:
log.error(
msg: str = (
f'No shm entry for end_time={end_time}, '
f'skipping rect'
)
await annot_req_stream.send(-1)
log.error(msg)
await annot_req_stream.send({'error': msg})
continue
# get close price from start bar, open from end
@ -587,7 +591,7 @@ class AnnotCtl(Struct):
start_time: float|None = None,
end_time: float|None = None,
) -> int:
) -> int|None:
'''
Add a `SelectRect` annotation to the target view, return
the instances `id(obj)` from the remote UI actor.
@ -610,7 +614,11 @@ class AnnotCtl(Struct):
'end_time': end_time,
},
})
aid: int = await ipc.receive()
aid: int|dict = await ipc.receive()
match aid:
case {'error': str(msg)}:
log.error(msg)
return None
self._ipcs[aid] = ipc
if not from_acm:
self._annot_stack.push_async_callback(
@ -692,7 +700,7 @@ class AnnotCtl(Struct):
# NEW: optional timestamp for server-side index lookup
time: float|None = None,
) -> int:
) -> int|None:
'''
Add a `SelectRect` annotation to the target view, return
the instances `id(obj)` from the remote UI actor.
@ -721,7 +729,12 @@ class AnnotCtl(Struct):
'time': time, # for server-side index lookup
},
})
aid: int = await ipc.receive()
aid: int|dict = await ipc.receive()
match aid:
case {'error': str(msg)}:
log.error(msg)
return None
self._ipcs[aid] = ipc
if not from_acm:
self._annot_stack.push_async_callback(
@ -748,7 +761,7 @@ class AnnotCtl(Struct):
# NEW: optional timestamp for server-side index lookup
time: float|None = None,
) -> int:
) -> int|None:
'''
Add a `pg.TextItem` annotation to the target view.
@ -772,7 +785,11 @@ class AnnotCtl(Struct):
'time': time, # for server-side index lookup
},
})
aid: int = await ipc.receive()
aid: int|dict = await ipc.receive()
match aid:
case {'error': str(msg)}:
log.error(msg)
return None
self._ipcs[aid] = ipc
if not from_acm:
self._annot_stack.push_async_callback(