Skip to content

feat!: 0.4.0: clear error messages, real timeouts, search filter and text, compile() chaining, install and poll resilience - #71

Merged
ashish-spext merged 7 commits into
video-db:mainfrom
videodb-engg:fix/sdk-dx
Nov 11, 2026
Merged

ashish-spext merged 7 commits into
video-db:mainfrom
videodb-engg:fix/sdk-dx

Conversation

@videodb-engg

@videodb-engg videodb-engg commented Nov 11, 2026 •

Copy link
Copy Markdown

Why

We audited the published videodb@0.3.2 against prod (api.videodb.io) and the docs. Several SDK behaviours make first-time users give up:

  • Errors don't say what went wrong.
  • search() returns nothing with no reason, and ignores filter.
  • search().compile() throws after the v0.3 change.
  • Long jobs end in "Unidentified Error".
  • npm install fails on the capture binary download.

Release this as a minor version: 0.4.0. Some of the fixes change what existing code sees. Each one is listed under "Upgrade notes" in CHANGELOG.md.

Changed (behaviour differs from 0.3.2)

0.3.2 0.4.0
Bad video id Error 400: Bad Request Error 400: Video not found
Bad API key Authentication Error: Authentication Error: Invalid API key
No API key Authentication Error: (hint only in cause) Authentication Error: No API key provided. Set an API key…
Tier budget used up Error 402: Payment Required Error 402: You have reached the … budget for this model tier…
Poll timeout VideodbError: Unidentified Error (timeout in cause.cause) RequestTimeoutError: Polling timed out after Ns. The job may still finish; its result will be at <url>
search({ filter }) Dropped Sent. An unfilterable field fails with the server's reason
Search V2 shot.text null Filled from metadata.embedded_text
uploadFile() missing path Upload failed, reason: File not found: <path>

Error classes, instanceof results, name and cause are unchanged.

Added

  • Error details: API errors carry three new fields:
    • status: the HTTP status, or a numeric error_code from a success: false body.
    • code: the server's error_code, e.g. llm_dollar_budget_reached.
    • data: the response body.
  • VdbBaseError exported: every SDK error extends it, so it works as a catch-all.
  • Search warnings: SearchResponse, SearchResult and AskResponse expose the server's warnings, e.g. why search() on a video with no new-style index came back empty. Nothing is printed.
  • SearchResponse chaining: it gains async compile(), play(), getEmbedCode() and getShotResults(), as in Python.
  • Typed uploads (type-only): uploadURL() and uploadFile() return Video, Audio or Image when mediaType is passed, and drop | undefined without a callbackUrl.
  • Skip the capture download: VIDEODB_SKIP_CAPTURE_INSTALL=1.

Fixed

  • Polling: up to 3 consecutive network errors, 429s or 5xx responses are retried.
  • npm install: it no longer fails or hangs when the capture binary download fails. Capture downloads the binary on first use.

README

Rewritten for the current API: connect, upload, understand → index → semanticSearch, ask, legacy search, EditorTimeline, subtitles and error handling. The old README taught the v0.1 API. The snippets were run against prod.

Testing

  • npx jest: 39 tests pass. They cover the new messages, the timeout class, filter forwarding, shot text, upload errors, error details and SearchResponse chaining.
  • npm run typecheck:tests: compile-time checks for upload return types.
  • tsc --noEmit and the build are clean. Lint and formatting warnings are unchanged from main.
  • Live against prod on the built branch:
    • Every error row in the table above.
    • search() with and without filter.
    • shot.text on new-style search hits.
    • SearchResponse.compile() returning a stream URL.
  • New Test workflow (.github/workflows/test.yml): typecheck, type tests, jest and build on every PR and push to main.

…install and polling

Errors
- Error messages now come from the server (e.g. "Error 402: You have reached
  the budget for this model tier..."), not the HTTP status text.
- All errors extend VideodbError and carry status, code (server error_code)
  and data. VdbBaseError is kept as a deprecated alias.

Search
- search() keeps the server's warnings on .warnings and prints each once,
  matching the Python SDK.
- search({ filter }) now sends the filter.
- Shots from new-style search fill text from metadata.
- SearchResponse gains getShotResults(), compile(), play() and
  getEmbedCode(), so search(...).compile() works again.

Uploads
- uploadURL()/uploadFile() return Video, Audio or Image when mediaType is
  given, and drop undefined when there is no callbackUrl.
- A missing local file fails with "File not found: <path>".

Install and polling
- The capture binary download never fails npm install, and
  VIDEODB_SKIP_CAPTURE_INSTALL=1 skips it. Fixed a hang on failed downloads.
- Polling retries network errors, 429 and 5xx. A timeout throws
  RequestTimeoutError with the output URL.

Docs and tests
- README rewritten for the current API.
- Added test/dx.spec.ts and compile-time upload type tests
  (npm run typecheck:tests).
…lbackUrl upload type

- e.cause on HTTP errors keeps its 0.3.2 shape, so e.cause.cause still holds
  the server message.
- new AuthenticationError(cause) still works; cause defaults to the message.
- uploadURL()/uploadFile() with a callbackUrl return the media type | undefined,
  as in 0.3.2, so existing if (result) guards still compile.
- CHANGELOG lists the remaining behaviour changes under Upgrade notes.
Restore 0.3.2 runtime behaviour exactly and keep only additions:
- Error classes, hierarchy, name, message and cause are as in 0.3.2. API
  errors additionally carry status, code and data (data.message is the
  server's explanation). VdbBaseError is exported as the catch-all.
- A poll timeout is wrapped exactly as before and also carries
  data.outputUrl.
- search() no longer prints warnings (still on .warnings), no longer sends
  filter, and shot.text is no longer back-filled, matching 0.3.2.
- uploadFile() error messages and flow are back to 0.3.2.

Kept: poll retries on transient failures, non-fatal capture install,
VIDEODB_SKIP_CAPTURE_INSTALL, SearchResponse compile/play/getEmbedCode,
search warnings on .warnings, and narrower upload return types.
- SearchResponse.compile()/play()/getEmbedCode() are async, so a non-shots
  response rejects instead of throwing synchronously.
- success:false errors carry status from a numeric error_code, matching
  HTTP errors.
- Comment the poll-retry policy (consecutive failures, no backoff) and the
  limits of UploadResult narrowing.
@videodb-engg videodb-engg changed the title fix: show server error messages, surface search warnings, harden install and polling fix: backward-compatible DX fixes: error details, search warnings, compile() chaining, install and poll resilience Nov 11, 2026
… shot text, upload errors

- Error messages include the server's explanation (Error 400: Video not
  found, Authentication Error: Invalid API key, the connect() hint).
  Network and unexpected errors include their reason. Classes and cause
  are unchanged.
- A poll timeout throws RequestTimeoutError with the output URL instead of
  VideodbError('Unidentified Error').
- search({ filter }) sends the filter on Video and Collection.
- Search V2 shots fill text from metadata.embeddedText.
- uploadFile() names a missing file (File not found: <path>) and other
  upload failures include their reason.

CHANGELOG lists these under Changed with upgrade notes; release as minor.
@videodb-engg videodb-engg changed the title fix: backward-compatible DX fixes: error details, search warnings, compile() chaining, install and poll resilience feat!: 0.4.0: clear error messages, real timeouts, search filter and text, compile() chaining, install and poll resilience Nov 11, 2026
@ashish-spext
ashish-spext merged commit d80d05c into video-db:main Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants